Name | Type | is_array | initial_value |
GKS_ApplyKnockup | trigger | No | |
GKS_CheckKnockup | trigger | No | |
GKS_CheckKnockupImmunity | trigger | No | |
GKS_GetRemainingTime | trigger | No | |
GKS_IsKnockupImmune | boolean | No | |
GKS_IsUnitKnockup | boolean | No | |
GKS_Param_Duration | real | No | |
GKS_Param_Flag | boolean | No | |
GKS_Param_Height | real | No | |
GKS_Param_Target | unit | No | |
GKS_RemainingTime | real | No | |
GKS_RemoveKnockup | trigger | No | |
GKS_SetKnockupImmunity | trigger | No | |
KnockupCancelledEvent | real | No | |
KnockupEventTarget | unit | No | |
KnockupLandingEvent | real | No | |
KnockupTakeoffEvent | real | No | |
TempPoint | location | No | |
TempReal | real | No | |
TempUnit | unit | No |
library PauseUnitEx /*
--------------
*/ requires /*
--------------
--------------------
*/ optional Table /*
--------------------
Link: "hiveworkshop.com/forums/showthread.php?t=188084"
--------------------
| PauseUnitEx |
| - MyPad |
--------------------
A simple snippet that grants additional functionality
to BlzPauseUnitEx that mimics PauseUnit
---------
| API |
---------
function PauseUnitEx(unit whichUnit, boolean flag)
- Internally calls BlzPauseUnitEx
function IsUnitPausedEx(unit whichUnit) -> boolean
- Checks if the unit is paused.
- This does not return accurate values when
BlzPauseUnitEx is called directly.
function GetUnitPauseExCounter(unit whichUnit) -> integer
- Returns the pause counter of the unit.
function SetUnitPauseExCounter(unit whichUnit, integer new)
- Sets the pause counter of the unit to the
new value. Internally calls BlzPauseUnitEx
when appropriate.
- Time Complexity: O(n)
*/
private module PauseM
static if LIBRARY_Table then
static Table map = 0
private static method onInit takes nothing returns nothing
set thistype.map = Table.create()
endmethod
else
static hashtable map = InitHashtable()
endif
static method getPauseCounter takes unit whichUnit returns integer
local integer counter = 0
local integer unitId = GetHandleId(whichUnit)
static if LIBRARY_Table then
set counter = map[unitId]
else
set counter = LoadInteger(map, 0, unitId)
endif
return counter
endmethod
static method pauseUnit takes unit whichUnit, boolean flag returns nothing
local integer counter = thistype.getPauseCounter(whichUnit)
local integer unitId = GetHandleId(whichUnit)
local integer incr = IntegerTertiaryOp(flag, 1, -1)
set counter = counter + incr
static if LIBRARY_Table then
set map[unitId] = counter
else
call SaveInteger(map, 0, unitId, counter)
endif
call BlzPauseUnitEx(whichUnit, flag)
endmethod
static method isPaused takes unit whichUnit returns boolean
local integer counter = thistype.getPauseCounter(whichUnit)
return counter > 0
endmethod
static method setPauseCounter takes unit whichUnit, integer new returns nothing
local integer counter = thistype.getPauseCounter(whichUnit)
local integer sign = 0
local integer unitId = GetHandleId(whichUnit)
local boolean flag = false
if new < counter then
set sign = -1
set flag = false
elseif new > counter then
set sign = 1
set flag = true
endif
loop
exitwhen counter == new
set counter = counter + sign
call BlzPauseUnitEx(whichUnit, flag)
endloop
static if LIBRARY_Table then
set map[unitId] = counter
else
call SaveInteger(map, 0, unitId, counter)
endif
endmethod
endmodule
private struct Pause extends array
implement PauseM
endstruct
function PauseUnitEx takes unit whichUnit, boolean flag returns nothing
call Pause.pauseUnit(whichUnit, flag)
endfunction
function SetUnitPauseExCounter takes unit whichUnit, integer new returns nothing
call Pause.setPauseCounter(whichUnit, new)
endfunction
function IsUnitPausedEx takes unit whichUnit returns boolean
return Pause.isPaused(whichUnit)
endfunction
function GetUnitPauseExCounter takes unit whichUnit returns integer
return Pause.getPauseCounter(whichUnit)
endfunction
endlibrary
library KnockupSystem /* version 1.1
*************************************************************************************
*
* ------------
* Description:
* ------------
* A simple knock-up system inspired by Mobile Legends & League of Legends.
* By yours truly, Rheiko.
*
* ---------
* Features:
* ---------
* - Allows you to apply knockup effect on a unit
* - Allows you to remove knockup effect from a unit
* - Allows you to check if a unit is being knocked up
* - Allows you to give knockup immunity to a unit
* - Allows you to remove knockup immunity from a unit
* - Allows you to check if a unit is immune to knockup effect
* - Allows you to check the remaining time of knockup effect on a unit
*
* ----
* API:
* ----
* function ApplyKnockup(unit whichUnit, real height, real duration)
* - Apply knockup effect on a unit
* - If the unit is already airborne from a previous knockup, the current effect will be **overridden**.
* - The new knockup will **blend smoothly** with the remaining height/time from the previous one, instead of resetting abruptly.
* - You can also configure this behavior from global configuration. (No override/Always override/Only stronger effect override)
*
* function RemoveKnockup(unit whichUnit) -> Returns a boolean value
* - Remove knockup effect from a unit
*
* function IsUnitKnockup(unit whichUnit) -> Returns a boolean value
* - Check if the unit is being knocked up
*
* function SetKnockupImmune(unit whichUnit, boolean flag) -> Returns a boolean value
* - Grants a unit immunity against knockup effect
*
* function IsKnockupImmune(unit whichUnit) -> Returns a boolean value
* - Check if the unit is immune to knockup
*
* function GetKnockupRemaining(unit whichUnit) -> Returns a real value
* - Check the remaining time of knockup effect on a unit
* - It will always return 0.0 if the unit is not airborne
*
* --------------
* */ requires /*
* --------------
* Knockup System has no requirement whatsoever.
*
* --------------------------
* */ optional PauseUnitEx /*
* --------------------------
* This snippet helps preventing the target from being unpaused early.
* Very useful if you use BlzPauseUnitEx for many things in your map
* and not just for this system.
*
* I highly recommend to use KnockupSystem along PauseUnitEx for the best outcomes.
*
* Credits to MyPad
* Link: https://www.hiveworkshop.com/threads/pauseunitex.326422/
*
* -------------------
* Import instruction:
* -------------------
* Simply copy and paste the Knockup System folder into your map. Easy Peasy Lemon Squeezy.
* If you want to use the optional library, then simply import it as well.
* But if you don't, you can simply delete it.
*
* ---------------------
* Global configuration:
* ---------------------
*/
globals
/*
Default duration value for knockup, used when the parameter value <= 0
*/
private constant real DEFAULT_KNOCKUP_DURATION = 1.0
/*
Default height value for knockup, used when the parameter value <= 0
*/
private constant real DEFAULT_KNOCKUP_HEIGHT = 150.0
/*
Max height value for knockup
*/
private constant real MAX_KNOCKUP_HEIGHT = 500.0
/*
Effect attached on the target during "airborne" state
*/
private constant string ATTACHMENT_EFFECT = "Abilities\\Spells\\Orc\\StasisTrap\\StasisTotemTarget.mdl"
/*
Unit attachment point (head, origin, overhead, etc)
*/
private constant string ATTACHMENT_POINT = "overhead"
/*
Effect on the location of the target when they get launched
*/
private constant string LAUNCH_EFFECT = ""
/*
Effect on the location of the target when they land
*/
private constant string LANDING_EFFECT = ""
/*
-1 = no override (wait until land), 0 = always override, 1 = only stronger duration override
*/
private constant integer OVERRIDE_MODE = 1
/*
Timer interval used to update target unit fly height
*/
private constant real TIMEOUT = .03125
/* -------------
END OF CONFIG
-------------
*/endglobals
globals
// Initialize hashtable
private hashtable TABLE = InitHashtable()
// Initialize timer
private timer TIMER = CreateTimer()
endglobals
native UnitAlive takes unit id returns boolean
function ApplyKnockup takes unit u, real height, real duration returns nothing
if height <= 0. then
set height = DEFAULT_KNOCKUP_HEIGHT
endif
if height > MAX_KNOCKUP_HEIGHT then
set height = MAX_KNOCKUP_HEIGHT
endif
if duration <= 0. then
set duration = DEFAULT_KNOCKUP_DURATION
endif
call KnockupInstance.create(u, height, duration)
endfunction
function RemoveKnockup takes unit u returns boolean
return KnockupInstance.Remove(u)
endfunction
function IsUnitKnockup takes unit u returns boolean
return KnockupInstance.IsKnockup(u)
endfunction
function SetKnockupImmune takes unit u, boolean flag returns boolean
return KnockupInstance.SetImmune(u, flag)
endfunction
function IsKnockupImmune takes unit u returns boolean
return KnockupInstance.IsImmune(u)
endfunction
function GetKnockupRemaining takes unit u returns real
return KnockupInstance.GetRemaining(u)
endfunction
private module LinkedList
thistype next
thistype prev
static method insert takes thistype this returns nothing
set this.next = 0
set this.prev = thistype(0).prev
set thistype(0).prev.next = this
set thistype(0).prev = this
endmethod
static method pop takes thistype this returns nothing
set this.next.prev = this.prev
set this.prev.next = this.next
endmethod
endmodule
struct KnockupInstance
implement LinkedList
boolean isAirborne
real height
real duration
real deltaHeight
real initialHeight
real baseHeight
real counter
unit target
effect sfx
static method IsKnockup takes unit u returns boolean
local integer key = GetHandleId(u)
local integer index = LoadInteger(TABLE, 0, key)
if index != 0 then
return KnockupInstance(index).isAirborne
endif
return false
endmethod
static method GetRemaining takes unit u returns real
local integer index = LoadInteger(TABLE, 0, GetHandleId(u))
if not (index == 0) then
if not thistype(index).isAirborne then
return 0.0
endif
return thistype(index).duration - thistype(index).counter
endif
return 0.0
endmethod
static method SetImmune takes unit u, boolean flag returns boolean
call SaveBoolean(TABLE, 1, GetHandleId(u), flag)
return true
endmethod
static method IsImmune takes unit u returns boolean
return LoadBoolean(TABLE, 1, GetHandleId(u))
endmethod
private static method CalculateApex takes real init, real peak, real base returns real
return (init + peak) * 2.0 - 0.5 * (init + base)
endmethod
static method Remove takes unit u returns boolean
local thistype this
local integer unitId = GetHandleId(u)
local integer index = LoadInteger(TABLE, 0, unitId)
local real x
local real y
if not (index == 0) then
set this = index
if this.isAirborne then
set this.isAirborne = false
call SetUnitFlyHeight(this.target, this.baseHeight, 0)
call RemoveSavedInteger(TABLE, 0, unitId)
static if LIBRARY_PauseUnitEx then
call PauseUnitEx(this.target, false)
else
call BlzPauseUnitEx(this.target, false)
endif
if UnitAlive(this.target) then
// Allows user to catch the event
set udg_KnockupEventTarget = this.target
set udg_KnockupCancelledEvent = 1.00
set udg_KnockupCancelledEvent = 0.00
set udg_KnockupEventTarget = null
endif
call DestroyEffect(this.sfx)
set this.sfx = null
call this.pop(this)
call this.destroy()
if thistype(0).next == 0 then
call PauseTimer(TIMER)
endif
return true
endif
endif
return false
endmethod
private static method Loop takes nothing returns nothing
local thistype this = thistype(0).next
local real t
local real a
local real b
local real x
local real y
loop
exitwhen this == 0
if IsImmune(this.target) or not UnitAlive(this.target) then
call KnockupInstance.Remove(this.target)
else
set this.counter = this.counter + TIMEOUT
set t = this.counter / this.duration
if t >= 1.0 then
call SetUnitFlyHeight(this.target, this.baseHeight, 0)
set this.isAirborne = false
call RemoveSavedInteger(TABLE, 0, GetHandleId(this.target))
set x = GetUnitX(this.target)
set y = GetUnitY(this.target)
static if LIBRARY_PauseUnitEx then
call PauseUnitEx(this.target, false)
else
call BlzPauseUnitEx(this.target, false)
endif
// Allows user to catch the event
set udg_KnockupEventTarget = this.target
set udg_KnockupLandingEvent = 1.00
set udg_KnockupLandingEvent = 0.00
set udg_KnockupEventTarget = null
call DestroyEffect(this.sfx)
set this.sfx = null
if LANDING_EFFECT != "" then
call DestroyEffect(AddSpecialEffect(LANDING_EFFECT, x, y))
endif
call this.pop(this)
call this.destroy()
if thistype(0).next == 0 then
call PauseTimer(TIMER)
endif
set this = this.next
else
set a = (1.0 - t)
set b = t
set this.deltaHeight = a * a * this.initialHeight + 2.0 * a * b * this.height + b * b * this.baseHeight
call SetUnitFlyHeight(this.target, this.deltaHeight, 0)
endif
// debug call BJDebugMsg("Current Fly Height of " + GetUnitName(this.target) + ":" + R2S(GetUnitFlyHeight(this.target)) )
endif
set this = this.next
endloop
endmethod
static method create takes unit target, real height, real duration returns thistype
local integer key = GetHandleId(target)
local thistype existing = LoadInteger(TABLE, 0, key)
local thistype this
local real x
local real y
local boolean shouldOverride
if target == null or IsImmune(target) then
return 0
endif
if not (existing == 0) then
if OVERRIDE_MODE == 0 then
debug call BJDebugMsg("DEBUG | Override always")
set shouldOverride = true
elseif OVERRIDE_MODE == 1 and duration > existing.duration - existing.counter then
debug call BJDebugMsg("DEBUG | Override only if stronger. Remaining duration: " + R2S(existing.duration - existing.counter) + " vs new: " + R2S(duration))
set shouldOverride = true
elseif OVERRIDE_MODE == -1 then
debug call BJDebugMsg("DEBUG | No Override")
return existing
endif
if shouldOverride then
set existing.duration = duration
set existing.counter = 0.0
set existing.initialHeight = GetUnitFlyHeight(existing.target)
set existing.height = CalculateApex(existing.initialHeight, height, existing.baseHeight)
if existing.height > MAX_KNOCKUP_HEIGHT then
set existing.height = MAX_KNOCKUP_HEIGHT
endif
endif
return existing
endif
set this = allocate()
call this.insert(this)
set this.target = target
set this.duration = duration
set this.isAirborne = true
set this.counter = 0.0
set this.initialHeight = GetUnitFlyHeight(this.target)
set this.baseHeight = GetUnitDefaultFlyHeight(this.target)
set this.height = CalculateApex(this.initialHeight, height, this.baseHeight)
if this.height > MAX_KNOCKUP_HEIGHT then
set this.height = MAX_KNOCKUP_HEIGHT
endif
call UnitAddAbility(this.target, 'Amrf')
call UnitRemoveAbility(this.target, 'Amrf')
set x = GetUnitX(this.target)
set y = GetUnitY(this.target)
static if LIBRARY_PauseUnitEx then
call PauseUnitEx(this.target, true)
else
call BlzPauseUnitEx(this.target, true)
endif
// Allows user to catch the event
set udg_KnockupEventTarget = this.target
set udg_KnockupTakeoffEvent = 1.00
set udg_KnockupTakeoffEvent = 0.00
set udg_KnockupEventTarget = null
set this.sfx = AddSpecialEffectTarget(ATTACHMENT_EFFECT, this.target, ATTACHMENT_POINT)
if LAUNCH_EFFECT != "" then
call DestroyEffect(AddSpecialEffect(LAUNCH_EFFECT, x, y))
endif
call SaveInteger(TABLE, 0, key, this)
// debug call BJDebugMsg("Current Fly Height of " + GetUnitName(this.target) + ":" + R2S(GetUnitFlyHeight(this.target)) )
if thistype(0).next == this then
call TimerStart(TIMER, TIMEOUT, true, function thistype.Loop)
endif
return this
endmethod
static method onInit takes nothing returns nothing
set thistype(0).next = thistype(0)
set thistype(0).prev = thistype(0)
endmethod
endstruct
endlibrary
scope KnockupSystemGUI initializer Init /*
*************************************************************************************
*
* ------------------
* Knockup System GUI
* ------------------
* This is a library containing GUI Wrappers for Knockup System by Rheiko.
* Intended for GUIers.
*
* --------
* Requires
* -------------
* KnockupSystem
* -------------
*
* --------------
* How to import:
* --------------
* 1. You need to first import KnockupSystem library
* 2. Copy the GUI API folder to your map
* 3. You are done!
*
* -----------
* How to use:
* -----------
* - Fill the variables that have _param prefix
* i.e: GKS_Param_Flag (boolean), GKS_Param_Height (real), GKS_Param_Target (unit), GKS_Param_Duration (real)
*
* - Run the trigger you want
* i.e:
* - GKS_ApplyKnockup (requirements: GKS_Param_Target, GKS_Param_Height, GKS_Param_Duration)
* Run this trigger to apply knockup effect on a unit
*
* - GKS_RemoveKnockup (requirements: GKS_Param_Target)
* Run this trigger to remove knockup effect from a unit
*
* - GKS_CheckKnockup (requirements: GKS_Param_Target)
* Run this trigger to check if a unit is being knocked up
*
* - GKS_CheckKnockupImmunity (requirements: GKS_Param_Target)
* Run this trigger to check if a unit is immune to knockup effects
*
* - GKS_SetKnockupImmunity (requirements: GKS_Param_Target, GKS_Param_Flag)
* Run this trigger to grant or remove knockup immunity from a unit
*
* - GKS_GetRemainingTime (requirements: GKS_Param_Target)
* Run this trigger to get the remaining time of knockup effect on a unit
*
*
* - Some that has return value will be stored inside these variables
* i.e:
* - GKS_IsUnitKnockup (boolean)
* Response to GKS_CheckKnockup trigger
*
* - GKS_IsKnockupImmune (boolean)
* Response to GKS_CheckKnockupImmunity trigger
*
* - GKS_RemainingTime (real)
* Response to GKS_GetRemainingTime trigger
*
* Note: Please check the GUI examples to understand further!
*
*************************************************************************************
*/
private function GUI_GetRemainingTime takes nothing returns nothing
set udg_GKS_RemainingTime = GetKnockupRemaining(udg_GKS_Param_Target)
endfunction
private function GUI_SetKnockupImmunity takes nothing returns nothing
call SetKnockupImmune(udg_GKS_Param_Target, udg_GKS_Param_Flag)
endfunction
private function GUI_CheckKnockupImmunity takes nothing returns nothing
set udg_GKS_IsKnockupImmune = IsKnockupImmune(udg_GKS_Param_Target)
endfunction
private function GUI_CheckKnockup takes nothing returns nothing
set udg_GKS_IsUnitKnockup = IsUnitKnockup(udg_GKS_Param_Target)
endfunction
private function GUI_RemoveKnockup takes nothing returns nothing
call RemoveKnockup(udg_GKS_Param_Target)
endfunction
private function GUI_ApplyKnockup takes nothing returns nothing
call ApplyKnockup(udg_GKS_Param_Target, udg_GKS_Param_Height, udg_GKS_Param_Duration)
endfunction
private function Init takes nothing returns nothing
set udg_GKS_ApplyKnockup = CreateTrigger()
set udg_GKS_RemoveKnockup = CreateTrigger()
set udg_GKS_CheckKnockup = CreateTrigger()
set udg_GKS_CheckKnockupImmunity = CreateTrigger()
set udg_GKS_SetKnockupImmunity = CreateTrigger()
set udg_GKS_GetRemainingTime = CreateTrigger()
call TriggerAddAction(udg_GKS_ApplyKnockup, function GUI_ApplyKnockup)
call TriggerAddAction(udg_GKS_RemoveKnockup, function GUI_RemoveKnockup)
call TriggerAddAction(udg_GKS_CheckKnockup, function GUI_CheckKnockup)
call TriggerAddAction(udg_GKS_CheckKnockupImmunity, function GUI_CheckKnockupImmunity)
call TriggerAddAction(udg_GKS_SetKnockupImmunity, function GUI_SetKnockupImmunity)
call TriggerAddAction(udg_GKS_GetRemainingTime, function GUI_GetRemainingTime)
endfunction
endscope
scope CustomShockwave initializer Init
globals
private timer TIMER = CreateTimer()
private unit array CASTER
private integer MAXINDEX = 0
private effect array MISSILE
private real array ANGLE
private real array CURDIST
private real array X
private real array Y
private group array GROUP
endglobals
native UnitAlive takes unit u returns boolean
private function OnLoop takes nothing returns nothing
local integer i = 0
local real x1
local real y1
local real x2
local real y2
local group g = CreateGroup()
local unit u
loop
set i = i + 1
exitwhen i > MAXINDEX
set X[i] = X[i] + (1050 * 0.03125) * Cos(ANGLE[i] * bj_DEGTORAD)
set Y[i] = Y[i] + (1050 * 0.03125) * Sin(ANGLE[i] * bj_DEGTORAD)
call BlzSetSpecialEffectX( MISSILE[i], X[i] )
call BlzSetSpecialEffectY( MISSILE[i], Y[i] )
set CURDIST[i] = CURDIST[i] + (1050 * 0.03125)
call GroupEnumUnitsInRange(g, X[i], Y[i], 125.0, null)
loop
set u = FirstOfGroup(g)
exitwhen u == null
if UnitAlive(u) and IsUnitEnemy(u, GetOwningPlayer(CASTER[i])) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) and not IsUnitInGroup(u, GROUP[i]) then
call UnitDamageTarget(CASTER[i], u, (25 + (50 * GetUnitAbilityLevel(CASTER[i], 'A000'))), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
call ApplyKnockup(u, 150, 0.7)
call GroupAddUnit(GROUP[i], u)
endif
call GroupRemoveUnit(g, u)
endloop
if CURDIST[i] >= 800.0 then
call DestroyEffect(MISSILE[i])
set CASTER[i] = CASTER[MAXINDEX]
set CASTER[MAXINDEX] = null
set CURDIST[i] = CURDIST[MAXINDEX]
set CURDIST[MAXINDEX] = .0
set X[i] = X[MAXINDEX]
set X[MAXINDEX] = .0
set Y[i] = Y[MAXINDEX]
set Y[MAXINDEX] = .0
set MISSILE[i] = MISSILE[MAXINDEX]
set MISSILE[MAXINDEX] = null
set ANGLE[i] = ANGLE[MAXINDEX]
set ANGLE[MAXINDEX] = .0
call GroupClear(GROUP[i])
set GROUP[i] = GROUP[MAXINDEX]
call DestroyGroup(GROUP[MAXINDEX])
set GROUP[MAXINDEX] = null
set i = i - 1
set MAXINDEX = MAXINDEX - 1
if MAXINDEX == 0 then
call PauseTimer(TIMER)
endif
endif
endloop
call DestroyGroup(g)
set g = null
endfunction
private function OnCast takes nothing returns boolean
local real x1
local real y1
local real x2
local real y2
local real a
local unit u
if GetSpellAbilityId() == 'A000' then
set u = GetTriggerUnit()
set x1 = GetUnitX(u)
set y1 = GetUnitY(u)
set x2 = GetSpellTargetX()
set y2 = GetSpellTargetY()
set a = Atan2(y2 - y1, x2 - x1) * bj_RADTODEG
set MAXINDEX = MAXINDEX + 1
set CASTER[MAXINDEX] = u
set CURDIST[MAXINDEX] = .0
set X[MAXINDEX] = x1
set Y[MAXINDEX] = y1
set ANGLE[MAXINDEX] = a
set MISSILE[MAXINDEX] = AddSpecialEffect("Abilities\\Spells\\Orc\\Shockwave\\ShockwaveMissile.mdl", x1, y1)
call BlzSetSpecialEffectHeight( MISSILE[MAXINDEX], 50.0 )
call BlzSetSpecialEffectOrientation( MISSILE[MAXINDEX], a * bj_DEGTORAD, 0.0, 0.0 )
if GROUP[MAXINDEX] == null then
set GROUP[MAXINDEX] = CreateGroup()
endif
if MAXINDEX == 1 then
call TimerStart(TIMER, 0.03125, true, function OnLoop)
endif
set u = null
return true
endif
return false
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function OnCast) )
set t = null
endfunction
endscope
scope CustomWarstomp initializer Init
globals
private integer INDEX = 0
private unit array CASTER
private real array X
private real array Y
private real array COUNTER
private real array COUNTER2
private group array GROUP
private timer TIMER = CreateTimer()
endglobals
private function DamageUnitInArea takes unit c, real x, real y returns nothing
local unit u
local group g = CreateGroup()
call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl", x, y))
call GroupEnumUnitsInRange(g, x, y, (200 + (GetUnitAbilityLevel(c, 'A001') * 50)), null)
loop
set u = FirstOfGroup(g)
exitwhen u == null
if UnitAlive(u) and IsUnitEnemy(u, GetOwningPlayer(c)) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) then
call UnitDamageTarget(c, u, (0 + (25 * GetUnitAbilityLevel(c, 'A001'))), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
call ApplyKnockup(u, 200, 0.9)
endif
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
set g = null
endfunction
private function OnLoop takes nothing returns nothing
local integer i = 0
local real x
local real y
local unit u
loop
set i = i + 1
exitwhen i > INDEX
set u = CASTER[i]
set x = X[i]
set y = Y[i]
set COUNTER[i] = COUNTER[i] + 0.03125
set COUNTER2[i] = COUNTER2[i] + 0.03125
if COUNTER2[i] >= 0.5 then
call DamageUnitInArea(u, x, y)
set COUNTER2[i] = .0
endif
if COUNTER[i] >= 1.0 then
set CASTER[i] = CASTER[INDEX]
set CASTER[INDEX] = null
set COUNTER[i] = COUNTER[INDEX]
set COUNTER[INDEX] = .0
set COUNTER2[i] = COUNTER2[INDEX]
set COUNTER2[INDEX] = .0
set X[i] = X[INDEX]
set X[INDEX] = .0
set Y[i] = Y[INDEX]
set Y[INDEX] = .0
call GroupClear(GROUP[i])
set GROUP[i] = GROUP[INDEX]
call DestroyGroup(GROUP[INDEX])
set GROUP[INDEX] = null
set i = i - 1
set INDEX = INDEX - 1
if INDEX == 0 then
call PauseTimer(TIMER)
endif
endif
endloop
endfunction
private function OnCast takes nothing returns boolean
local real x
local real y
local unit u
if GetSpellAbilityId() == 'A001' then
set u = GetTriggerUnit()
set x = GetUnitX(u)
set y = GetUnitY(u)
set INDEX = INDEX + 1
set CASTER[INDEX] = u
set COUNTER[INDEX] = .0
set COUNTER2[INDEX] = .0
set X[INDEX] = x
set Y[INDEX] = y
if GROUP[INDEX] == null then
set GROUP[INDEX] = CreateGroup()
endif
call DamageUnitInArea(u, x, y)
if INDEX == 1 then
call TimerStart(TIMER, 0.03125, true, function OnLoop)
endif
endif
return false
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function OnCast) )
set t = null
endfunction
endscope