Name | Type | is_array | initial_value |
AT | unit | Yes | |
AttackTimes | integer | No | |
BlizzAuto | integer | No | |
BossGodLikeTime | timer | No | |
BossGodLikeTW | timerdialog | No | |
BossLevel | integer | No | |
BossTime | timer | No | |
caster | unit | No | |
CasterLoc | location | No | |
CdGDmg | real | No | |
ChoseHero | integer | Yes | |
CountdownTimer | timerdialog | No | |
DialogButtons | button | Yes | |
DruidBall | unit | No | |
DS | group | No | |
DS_High | real | Yes | |
DS_P | location | Yes | |
DS_TAR | unit | Yes | |
DS_YA | boolean | Yes | |
DSs | integer | No | |
DummyEthernalPower | unit | No | |
DummyWarlock | unit | No | |
EB_AoE | real | No | |
EB_Arc_Dist | real | No | |
EB_Arc_Str | real | No | |
EB_Blade_Speed | real | No | |
EB_Caster | unit | No | |
EB_Damage | real | No | |
EB_Location | location | No | |
EB_Mana_Drain | real | No | |
EB_Offset_Loc | location | Yes | |
EB_Order | string | No | |
EB_Part | unit | Yes | |
EB_Part_Amount | integer | No | |
EB_SFX | string | No | |
EB_Timer | timer | No | |
EB_Timer_Delay | real | No | |
Firelords | unit | No | |
FirelordsEnabled | boolean | No | |
Frostball | unit | Yes | |
HeroChoose | integer | No | |
HeroDialog1 | dialog | No | |
HeroDialog2 | dialog | No | |
Heroes | unitcode | Yes | |
HK_Location | location | No | |
HK_Location2 | location | No | |
HK_Location3 | location | No | |
HK_Location4 | location | No | |
HK_Target_Unit | unit | No | |
HK_TC | unit | No | |
HolyLanceDummy | unit | Yes | |
HolyQueen | unit | No | |
HolyQueenEnabled | boolean | No | |
Lichlord | unit | No | |
LichlordEnabled | boolean | No | |
Lightning | lightning | Yes | |
LightningWayLoop | integer | No | |
Loop_SP | integervar | No | |
MarkLoop | integer | No | |
MassTeleport_Caster | unit | No | |
MassTeleport_Effect | effect | No | |
MassTeleport_FadeTime | real | No | |
MassTeleport_Group | group | No | |
MassTeleport_Target | location | No | |
NatureLord | unit | No | |
NatureLordEnabled | boolean | No | |
NatureRaider | unit | Yes | |
NatureRaiderLoc | location | Yes | |
Nova_Angle | real | Yes | |
Nova_Booleen | boolean | Yes | |
Nova_Caster | unit | Yes | |
Nova_Counter | real | No | |
Nova_Damage | real | Yes | |
Nova_Distance | real | Yes | |
Nova_Effects | string | Yes | |
Nova_Index | integer | No | |
Nova_Integer | integervar | No | |
Nova_Number | real | No | |
Nova_Point | location | Yes | |
Nova_RemainingTime | real | Yes | |
NovaLoop | integer | No | |
NumbA | integer | No | |
OmniTimes | integer | No | |
RandomHero | integer | No | |
ShockwaveUnits | unit | No | |
SonicBloawAT | integer | No | |
SP | group | No | |
SP_Caster | unit | Yes | |
SP_Chain | unit | Yes | |
SP_Group | group | Yes | |
SP_Jumps | integer | Yes | |
SP_Point | location | Yes | |
SP_Target | unit | Yes | |
STRPUDGE_Point | location | Yes | |
TargetPoint | location | No | |
TargetUnit | unit | No | |
TempPoint | location | No | |
TempPoint1 | location | No | |
TempPoint2 | location | No | |
TestReal | real | No | |
TestUnit | unit | No | |
ThunderClapLT | location | No | |
Times5 | integer | No | |
Times6 | integer | No | |
UnitGroups | group | Yes | |
Warden | unit | No | |
WardenEnabled | boolean | No | |
WardenSF | effect | Yes | |
Warlock | unit | No | |
WarlockEnabled | boolean | No | |
Waterlord | unit | No | |
WaterlordEnabled | boolean | No | |
WF_Angle | real | No | |
WF_Aoe | real | No | |
WF_Caster | unit | Yes | |
WF_CustomV | integer | No | |
WF_Damage | real | No | |
WF_DamageAlready | group | Yes | |
WF_HeroPoint | location | No | |
WF_Level | integer | Yes | |
WF_MuiCount | integer | No | |
WF_MuiGroup | group | No | |
WF_Offset | location | No | |
WF_RealOffset | real | No | |
WF_SpellDMG | real | No | |
WF_SpellPoint | location | Yes |
//TESH.scrollpos=213
//TESH.alwaysfold=0
//==============================================================================
// PUI -- Perfect Unit Indexing by Cohadar -- v5.3
//==============================================================================
//
// PURPOUSE:
// * Extending UnitUserData()
// * This is basically perfect hashing algorithm for units
//
// HOW TO USE:
// * You have only one function at your disposal GetUnitIndex(unit)
// It will return a unique index for each unit in range 1..8190
//
// * What you will do with that index is all up to you
// Of course using global arrays is the most obvious choice
// Advanced jassers will think of a couple of more clever ones ofc.
//
// * There are also 2 textmacros available at the end of library code
// They can be used for easier attaching to units
// PUI for structs
// PUI_PROPERTY for unit, integer, real, boolean and string variables
//
// PROS:
// * You can use any number of systems that previously could not work together
// because they all required exclusive access of UnitUserData()
//
// * You can also use this to attach spell data structs to casters
//
// * There are no SetUnitIndex() or ClearUnitIndex() functions here
// Each unit gets assigned one index that cannot be changed
// That index will be automatically recycled when unit is removed from the game.
//
// CONS:
// * This system uses UnitUserData() itself
// That means that if you want to use PUI you must recode
// any other system that uses UnitUserData() to use GetUnitIndex() instead
//
// * If you use UnitIndex for arrays of non-native types (timers, effects and similar)
// you must check if timer on that index already exists before you create a new one.
// This can happen if GetUnitIndex() assigns a recycled index (index of some dead and removed unit)
// to the newly created unit for which you intended to use timer for
//
// * All in all this is not a sys for newbies, it gives great power,
// but it requires knowledge and carefull handling
//
// DETAILS:
// * System is using unit array to keep track of all units with an index.
// Array is periodically checked for removed units,
// when removed unit is found, index is recycled.
// Indexes have "decay time" to prevent bugs
// caused by attaching to "Can't Raise, Does not decay" type units,
// or by using RemoveUnit() function
//
// SYSTEM COMMANDS: (debug mode only, red player only)
//
// * type -pui to display indexes of currently selected units
// * type -puistats to display some stats
// * type -puitest to verify that all indexes are valid and unique
//
// THANKS TO:
// * Vexorian - for his help with PUI textmacro
// * Builder Bob - for testing and bugfinding
// * Joker(Div) - bugfinding
//
// HOW TO IMPORT:
// * Just create a trigger named PUI
// * convert it to text and replace the whole trigger text with this one
//
//==============================================================================
library PUI initializer Init
//==============================================================================
globals
//-----------------------------------------------
private constant real INDEX_DECAY_TIME = 5. // seconds
//-----------------------------------------------
private constant real PERIOD = 0.03125 // 32 fps
//-----------------------------------------------
private constant integer DECAY_TICKS = R2I(INDEX_DECAY_TIME/PERIOD)
//-----------------------------------------------
private integer maxIndex = 0
private integer usedIndexCount = 0
private integer checker = 0
private integer array Indexz
private unit array Unitz
//-----------------------------------------------
private integer freeIndexCount = 0
private integer array Freez
//-----------------------------------------------
private integer decayIndexCount = 0
private integer decayer = 0
private integer array Decayz
private integer array TimeEndz
private integer tick = 0
endglobals
//==============================================================================
private function PeriodicRecycler takes nothing returns boolean
set tick = tick + 1
// unit recycler
if usedIndexCount > 0 then
set checker = checker + 1
if checker > usedIndexCount then
set checker = 1
endif
if (GetUnitUserData(Unitz[checker]) == 0) then
set decayIndexCount = decayIndexCount + 1
set Decayz[decayIndexCount] = Indexz[checker]
set TimeEndz[decayIndexCount] = tick + DECAY_TICKS
set Indexz[checker] = Indexz[usedIndexCount]
set Unitz[checker] = Unitz[usedIndexCount]
set usedIndexCount = usedIndexCount - 1
endif
endif
// index recycler
if decayIndexCount > 0 then
set decayer = decayer + 1
if decayer > decayIndexCount then
set decayer = 1
endif
if TimeEndz[decayer] <= tick then
set freeIndexCount = freeIndexCount + 1
set Freez[freeIndexCount] = Decayz[decayer]
set Decayz[decayer] = Decayz[decayIndexCount]
set TimeEndz[decayer] = TimeEndz[decayIndexCount]
set decayIndexCount = decayIndexCount - 1
endif
endif
// for debugging
//if ModuloInteger(tick, 8) == 0 then
// call ClearTextMessages()
// call BJDebugMsg("Used/Free/Decaying: " + I2S(usedIndexCount) + "/" + I2S(freeIndexCount) + "/" + I2S(decayIndexCount))
//endif
return false
endfunction
//==============================================================================
// Main and only function exported by this library
//==============================================================================
function GetUnitIndex takes unit whichUnit returns integer
local integer index
debug if whichUnit == null then
debug call BJDebugMsg("|c00FF0000ERROR: PUI - Index requested for null unit")
debug return 0
debug endif
set index = GetUnitUserData(whichUnit)
if index == 0 then
set usedIndexCount = usedIndexCount + 1
if freeIndexCount > 0 then
set Indexz[usedIndexCount] = Freez[freeIndexCount]
set freeIndexCount = freeIndexCount - 1
else
set maxIndex = maxIndex + 1
set Indexz[usedIndexCount] = maxIndex
endif
set Unitz[usedIndexCount] = whichUnit
call SetUnitUserData(whichUnit, Indexz[usedIndexCount])
set index = GetUnitUserData(whichUnit)
// this happens when requesting unit index for removed unit
debug if index == 0 then
debug call BJDebugMsg("|c00FFCC00WARNING: PUI - Bad unit handle")
debug endif
endif
return index
endfunction
//==============================================================================
private function DisplayStats takes nothing returns nothing
call BJDebugMsg("=============================================")
call BJDebugMsg("Biggest index ever = " + I2S(maxIndex))
call BJDebugMsg("Indexes in use = " + I2S(usedIndexCount))
call BJDebugMsg("Decaying indexes = " + I2S(decayIndexCount))
call BJDebugMsg("Released indexes = " + I2S(freeIndexCount))
call BJDebugMsg("=============================================")
endfunction
//===========================================================================
private function DisplaySelectedEnum takes nothing returns nothing
call BJDebugMsg( "PUI(" + ( GetUnitName(GetEnumUnit()) + ( ") = " + I2S(GetUnitUserData(GetEnumUnit())) ) ) )
endfunction
//===========================================================================
private function DisplaySelected takes nothing returns nothing
local group g = CreateGroup()
call SyncSelections()
call GroupEnumUnitsSelected(g, Player(0), null)
call ForGroup(g, function DisplaySelectedEnum)
call DestroyGroup(g)
set g = null
endfunction
//==============================================================================
globals
private integer testCounter = 0
private integer array TestCountz
endglobals
//==============================================================================
private function Test takes nothing returns nothing
local integer i
set testCounter = testCounter + 1
set i = 1
loop
exitwhen i > usedIndexCount
// happens when you abuse UnitUserData outside PUI
if GetUnitTypeId(Unitz[i]) != 0 and GetUnitUserData(Unitz[i]) != Indexz[i] then
call BJDebugMsg("|c00FF0000ERROR: PUI - Invalid index detected")
return
endif
// if this error happens it means PUI is bugged
if TestCountz[Indexz[i]] != testCounter then
set TestCountz[Indexz[i]] = testCounter
else
call BJDebugMsg("|c00FF0000ERROR: PUI - Double index detected")
return
endif
set i = i + 1
endloop
call BJDebugMsg("|c0000ff00OK: PUI - All indexes were valid and unique")
endfunction
//==============================================================================
private function Init takes nothing returns nothing
local trigger trig
set trig = CreateTrigger()
call TriggerRegisterTimerEvent( trig, PERIOD, true )
call TriggerAddCondition( trig, Condition(function PeriodicRecycler) )
debug set trig = CreateTrigger()
debug call TriggerRegisterPlayerChatEvent( trig, Player(0), "-pui", true )
debug call TriggerAddAction( trig, function DisplaySelected )
debug set trig = CreateTrigger()
debug call TriggerRegisterPlayerChatEvent( trig, Player(0), "-puistats", true )
debug call TriggerAddAction( trig, function DisplayStats )
debug set trig = CreateTrigger()
debug call TriggerRegisterPlayerChatEvent( trig, Player(0), "-puitest", true )
debug call TriggerAddAction( trig, function Test )
endfunction
endlibrary
//===========================================================================
// Allowed PUI_PROPERTY TYPES are: unit, integer, real, boolean, string
// Do NOT put handles that need to be destroyed here (timer, trigger, ...)
// Instead put them in a struct and use PUI textmacro
//===========================================================================
//! textmacro PUI_PROPERTY takes VISIBILITY, TYPE, NAME, DEFAULT
$VISIBILITY$ struct $NAME$
private static unit array pui_unit
private static $TYPE$ array pui_data
//-----------------------------------------------------------------------
// Returns default value when first time used
//-----------------------------------------------------------------------
static method operator[] takes unit whichUnit returns $TYPE$
local integer pui = GetUnitIndex(whichUnit)
if .pui_unit[pui] != whichUnit then
set .pui_unit[pui] = whichUnit
set .pui_data[pui] = $DEFAULT$
endif
return .pui_data[pui]
endmethod
//-----------------------------------------------------------------------
static method operator[]= takes unit whichUnit, $TYPE$ whichData returns nothing
local integer pui = GetUnitIndex(whichUnit)
set .pui_unit[pui] = whichUnit
set .pui_data[pui] = whichData
endmethod
endstruct
//! endtextmacro
//===========================================================================
// Never destroy PUI structs directly.
// Use .release() instead, will call .destroy()
//===========================================================================
//! textmacro PUI
private static unit array pui_unit
private static integer array pui_data
private static integer array pui_id
//-----------------------------------------------------------------------
// Returns zero if no struct is attached to unit
//-----------------------------------------------------------------------
static method operator[] takes unit whichUnit returns integer
local integer pui = GetUnitIndex(whichUnit)
if .pui_data[pui] != 0 then
if .pui_unit[pui] != whichUnit then
// recycled handle detected
call .destroy(.pui_data[pui])
set .pui_unit[pui] = null
set .pui_data[pui] = 0
endif
endif
return .pui_data[pui]
endmethod
//-----------------------------------------------------------------------
// This will overwrite already attached struct if any
//-----------------------------------------------------------------------
static method operator[]= takes unit whichUnit, integer whichData returns nothing
local integer pui = GetUnitIndex(whichUnit)
if .pui_data[pui] != 0 then
call .destroy(.pui_data[pui])
endif
set .pui_unit[pui] = whichUnit
set .pui_data[pui] = whichData
set .pui_id[whichData] = pui
endmethod
//-----------------------------------------------------------------------
// If you do not call release struct will be destroyed when unit handle gets recycled
//-----------------------------------------------------------------------
method release takes nothing returns nothing
local integer pui= .pui_id[integer(this)]
call .destroy()
set .pui_unit[pui] = null
set .pui_data[pui] = 0
endmethod
//! endtextmacro
//TESH.scrollpos=24
//TESH.alwaysfold=0
function Trig_Ice_Boss_Blizzard_AA_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A00I' ) ) then
return false
endif
return true
endfunction
function Trig_Ice_Boss_Blizzard_AA_Actions takes nothing returns nothing
local unit Caster
local location CasterLoc
local location TargetPoint
local real Angle
local location TempPoint
local unit Dummy
set Caster = GetSpellAbilityUnit()
set CasterLoc = GetUnitLoc(Caster)
set TargetPoint = GetSpellTargetLoc()
set Angle = AngleBetweenPoints(CasterLoc, TargetPoint)
set bj_forLoopBIndex = 1
set bj_forLoopBIndexEnd = 5
loop
exitwhen bj_forLoopBIndex > bj_forLoopBIndexEnd
set TempPoint = PolarProjectionBJ(CasterLoc, ( 200.00 * I2R(GetForLoopIndexB()) ), Angle)
call CreateNUnitsAtLoc( 1, 'n000', GetOwningPlayer(Caster), TempPoint, bj_UNIT_FACING )
set Dummy=GetLastCreatedUnit()
call UnitApplyTimedLifeBJ( 5.00, 'BTLF', Dummy )
call UnitAddAbilityBJ( 'AHbz', Dummy )
call IssuePointOrderLocBJ( Dummy, "blizzard", TempPoint )
call RemoveLocation (TempPoint)
call PolledWait( 0.10 )
set bj_forLoopBIndex = bj_forLoopBIndex + 1
endloop
call RemoveLocation (udg_CasterLoc)
call RemoveLocation (udg_TargetPoint)
endfunction
//===========================================================================
function InitTrig_Ice_Boss_Blizzard_AA takes nothing returns nothing
set gg_trg_Ice_Boss_Blizzard_AA = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Ice_Boss_Blizzard_AA, EVENT_PLAYER_UNIT_SPELL_CAST )
call TriggerAddCondition( gg_trg_Ice_Boss_Blizzard_AA, Condition( function Trig_Ice_Boss_Blizzard_AA_Conditions ) )
call TriggerAddAction( gg_trg_Ice_Boss_Blizzard_AA, function Trig_Ice_Boss_Blizzard_AA_Actions )
endfunction
//TESH.scrollpos=24
//TESH.alwaysfold=0
function Trig_Frost_Armor_Conditions takes nothing returns boolean
if ( not ( udg_LichlordEnabled == true ) ) then
return false
endif
return true
endfunction
function Trig_Frost_Armor_Actions takes nothing returns nothing
set bj_forLoopAIndex = 1
set bj_forLoopAIndexEnd = 100
loop
exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
call AddSpecialEffectLocBJ( PolarProjectionBJ(GetUnitLoc(udg_Lichlord), 200.00, ( 3.60 * I2R(GetForLoopIndexA()) )), "Abilities\\Spells\\Human\\Blizzard\\BlizzardTarget.mdl" )
set bj_forLoopAIndex = bj_forLoopAIndex + 1
endloop
call TriggerSleepAction( 0.25 )
set bj_forLoopAIndex = 1
set bj_forLoopAIndexEnd = 100
loop
exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
call AddSpecialEffectLocBJ( PolarProjectionBJ(GetUnitLoc(udg_Lichlord), 300.00, ( 3.60 * I2R(GetForLoopIndexA()) )), "Abilities\\Spells\\Human\\Blizzard\\BlizzardTarget.mdl" )
set bj_forLoopAIndex = bj_forLoopAIndex + 1
endloop
call TriggerSleepAction( 0.25 )
set bj_forLoopAIndex = 1
set bj_forLoopAIndexEnd = 100
loop
exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
call AddSpecialEffectLocBJ( PolarProjectionBJ(GetUnitLoc(udg_Lichlord), 400.00, ( 3.60 * I2R(GetForLoopIndexA()) )), "Abilities\\Spells\\Human\\Blizzard\\BlizzardTarget.mdl" )
set bj_forLoopAIndex = bj_forLoopAIndex + 1
endloop
call TriggerSleepAction( 0.25 )
set bj_forLoopAIndex = 1
set bj_forLoopAIndexEnd = 16
loop
exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
call TriggerSleepAction( 0.02 )
call AddSpecialEffectLocBJ( PolarProjectionBJ(GetUnitLoc(udg_Lichlord), 500.00, ( 40.00 * I2R(GetForLoopIndexA()) )), "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl" )
call CreateNUnitsAtLoc( 1, 'u005', Player(10), PolarProjectionBJ(GetUnitLoc(udg_Lichlord), 500.00, ( 40.00 * I2R(GetForLoopIndexA()) )), bj_UNIT_FACING )
set bj_forLoopAIndex = bj_forLoopAIndex + 1
endloop
endfunction
//===========================================================================
function InitTrig_Frost_Armor takes nothing returns nothing
set gg_trg_Frost_Armor = CreateTrigger( )
call TriggerRegisterTimerEventPeriodic( gg_trg_Frost_Armor, 40.00 )
call TriggerAddCondition( gg_trg_Frost_Armor, Condition( function Trig_Frost_Armor_Conditions ) )
call TriggerAddAction( gg_trg_Frost_Armor, function Trig_Frost_Armor_Actions )
endfunction
//TESH.scrollpos=12
//TESH.alwaysfold=0
scope Fervor initializer Init
globals
private constant integer ABIL_ID = 'A00G'
private constant integer ATTACK_SPEED_ID = 'A01D'
endglobals
private struct Data
unit cs
integer stacklevel
unit lasttarg
method onDestroy takes nothing returns nothing
set this.lasttarg = null
endmethod
//! runtextmacro PUI()
endstruct
private function Act2 takes nothing returns nothing
local Data d = Data[GetAttacker()]
if d.lasttarg == GetTriggerUnit() then
if d.stacklevel < 20 then
set d.stacklevel = d.stacklevel + GetUnitAbilityLevel(d.cs,ABIL_ID)
endif
return
else
set d.stacklevel = d.stacklevel / 2
set d.lasttarg = GetTriggerUnit()
endif
debug call BJDebugMsg("Attack Speed Bonus : " + I2S(d.stacklevel * 5) + "%" )
call SetUnitAbilityLevel(d.cs,ATTACK_SPEED_ID,d.stacklevel)
endfunction
private function Cond2 takes nothing returns boolean
return Data[GetAttacker()] != 0
endfunction
private function Act takes nothing returns nothing
local Data d = Data.create()
set d.cs = GetTriggerUnit()
set d.stacklevel = 1
call UnitAddAbility(d.cs,ATTACK_SPEED_ID)
set Data[d.cs] = d
endfunction
private function Cond takes nothing returns boolean
return GetUnitAbilityLevel(GetTriggerUnit(),ABIL_ID) == 1
endfunction
private function Init takes nothing returns nothing
local trigger t
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_HERO_SKILL)
call TriggerAddCondition(t,Condition(function Cond))
call TriggerAddAction(t,function Act)
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_ATTACKED)
call TriggerAddCondition(t,Condition(function Cond2))
call TriggerAddAction(t,function Act2)
endfunction
endscope
//TESH.scrollpos=6
//TESH.alwaysfold=0
function Trig_Lightning_Way_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A01E' ) ) then
return false
endif
return true
endfunction
function Trig_Lightning_Way_Func001Func004A takes nothing returns nothing
call UnitDamageTargetBJ( GetSpellAbilityUnit(), GetEnumUnit(), ( 100.00 + ( 100.00 * I2R(GetUnitAbilityLevelSwapped('A01E', GetSpellAbilityUnit())) ) ), ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
endfunction
function Trig_Lightning_Way_Actions takes nothing returns nothing
local unit caster = GetSpellAbilityUnit()
local real caster_facing = GetUnitFacing(caster)
local integer LightningWayLoop
local real point_release
local location caster_loc = GetUnitLoc(caster)
set LightningWayLoop = 1
loop
exitwhen LightningWayLoop > 20
set point_release = -100.00 + ( 50.00 * I2R(LightningWayLoop) )
call TriggerSleepAction( 0.04 )
call CreateNUnitsAtLoc( 1, 'n00U', GetOwningPlayer(GetSpellAbilityUnit()), PolarProjectionBJ(caster_loc, point_release, caster_facing), bj_UNIT_FACING )
call UnitApplyTimedLifeBJ( 0.50, 'BTLF', GetLastCreatedUnit() )
call ForGroupBJ( GetUnitsInRangeOfLocAll(200.00, GetUnitLoc(GetLastCreatedUnit())), function Trig_Lightning_Way_Func001Func004A )
set LightningWayLoop = LightningWayLoop + 1
endloop
if LightningWayLoop==20 then
set caster=null
else
call DoNothing( )
endif
endfunction
//===========================================================================
function InitTrig_Lightning_Way takes nothing returns nothing
set gg_trg_Lightning_Way = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Lightning_Way, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Lightning_Way, Condition( function Trig_Lightning_Way_Conditions ) )
call TriggerAddAction( gg_trg_Lightning_Way, function Trig_Lightning_Way_Actions )
endfunction