Name | Type | is_array | initial_value |
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope RainOfArrow //version 1.04
/*---------------------------------------------------------------------------------------------------------
*
* Requires:
*
*-----------------------------------------------------------------------------------------------------------
*
* - CTL [By Nestharus]
* - WorldBounds [By Nestharus]
* - IsDestructableTree [By PitzerMike]
* - SpellEffectEvent [By Bribe]
* - RegisterPlayerUnitEvent [By Magtheridon9]
*
*-----------------------------------------------------------------------------------------------------------
*
* How to import:
*
*-----------------------------------------------------------------------------------------------------------
*
* - Copy Rain of Cold Arrows Ability from object editor ---> Abilities
* - Copy Rain of Cold Arrows (slow) Ability from objest editor ---> Abilities
* - Copy Rain of Cold Arrows (slow) Buff from object editor ---> Buffs/Effects
* - Copy Rain of Cold Arrows - Dummy 1 from objedt editor ---> Units
* - Copy Rain of Cold Arrows - Dummy 2 from object editor ---> Units
* - Copy Rain of Cold Arrows Trigger from Trigger editor
* - Copy Libraries folder from Trigger editor
*
*-----------------------------------------------------------------------------------------------------------
*
* Changelog:
*
*-----------------------------------------------------------------------------------------------------------
*
* v1.0
* - First release.
* v1.01
* - Moved Fire struct over Jump struct.
* - Removed onCast functions and inlined in to onRun function changing it's name to onCast.
* - Speed[this] now have value of global varaiable SPEED not 10 like it was before.
* - Removed unused libraries.
* v1.02
* - Added Z damage range dor now arrows can hit flying units.
* - Added dummy death effect.
* - Added SlowFilter function.
* - Now you can spawn more than arrows at once.
* - Removed GroupUtils and now using one group for damage
* - Privatized Fire struct
* v1.03
* - Removed some leaks
* - Now using one dummy to apply slow
* - Renamed some globals
* - Remove unused dummy
* v1.04
* - Changed some globals named
* - Now using global dmmy to apply debuffs
*
*-----------------------------------------------------------------------------------------------------------*/
/**************************************************************************************
* *
* CONFIGURATION *
* *
**************************************************************************************/
globals
/*Main ability rawcode*/
private constant integer SPELL_CODE = 'A000'
/*Slow ability rawcode*/
private constant integer SLOW_CODE = 'A001'
/*/Dummy - 1 rawcode*/
private constant integer DUMMY_CODE = 'h000'
/*Dummy - 2 rawcode*/
private constant integer DUMMY_CODE2 = 'h003'
/*Storm crow ability rawcode*/
private constant integer CROW_CODE = 'Arav'
/*Max jump height*/
private constant real MAX_HEIGHT = 225
/*Jump total distance traveled*/
private constant real DISTANCE = 250
/*Jump move speed*/
private constant real SPEED = 10
/*Arrows spawn in signle shot*/
private constant integer S_AMMOUT = 2
/*Distance at which archer will start shooting arrows*/
private constant real S_DISTANCE = 70
/*Jump move speed when only shooting*/
private constant real S_SPEED = 1.00
/*Shoting dummy height. It's caster's height + this value
to make arrows appear from bow not from feet*/
private constant real S_HEIGHT = 80
/*Arrows size 1 = 100%, 0.5 = 50%*/
private constant real S_SCALE = 1.10
/*Arrows will not spawn on caster*/
/*It will spawn on caster's location + this value*/
private constant real S_CREATE_OFF = 20
/*Caster's animation while shooting*/
private constant string S_ANIM = "attack"
/*Every X timer ticks (0.031250) player caster's animation*/
private constant integer S_ANIM_CD = 6
/*Every X timer ticks (0.031250) spawn arrow*/
private constant integer S_SPAWN_CD = 5
/*Arrows move speed*/
private constant real F_SPEED = 25
/*Arrows death animation when it land on the ground*/
private constant string F_ANIM = "death"
/*Arrows death effect size*/
private constant real F_D_SCALE = 1
/*Arrows death effect expiration time*/
private constant real F_D_LT = 1.2
/*Arrows death effect animation*/
private constant string F_D_ANIM = "death"
/*Arrows damage range*/
private constant real DAMAGE_RANGE = 50
/*Arrows Z damage range*/
private constant real Z_DAMAGE_RANGE = 25
/*Damage and attack type*/
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_MAGIC
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_DEATH
/*Should arrows kill trees?*/
private constant boolean DESTROY_TREE = true
/*Should arrows slow enemy targets?*/
private constant boolean SLOW = true
endglobals
/**************************************************************************************
* *
* FUNCTIONS CONFIGURATION *
* *
**************************************************************************************/
/*Damage dealt per arrow in DAMAGE_RANGE*/
private function GetDamage takes integer level returns real
return level * 15.00
endfunction
/*Arena of effect. Arrows will move from caster's location*/
/*to random point in target location based on this value*/
private function GetAoE takes integer level returns real
return level * 25.00 + 75.00
endfunction
/*Total ammout of arrows spawned*/
private function GetArrows takes integer level returns integer
return level * 5 + 15
endfunction
/*Damage filter function, you can set which units should not be damaged by spell*/
private function TargetFilter takes unit u, player p returns boolean
return IsUnitEnemy(u, p) and not IsUnitType(u, UNIT_TYPE_DEAD) and not IsUnitType(u, UNIT_TYPE_STRUCTURE)
endfunction
private function SlowFilter takes unit u, player p returns boolean
return IsUnitEnemy(u, p) and not IsUnitType(u, UNIT_TYPE_DEAD) and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) and not IsUnitType(u, UNIT_TYPE_MECHANICAL)
endfunction
/**************************************************************************************
* *
* CONFIGURATION END *
* *
**************************************************************************************/
private function ParabolaZ2 takes real y0, real y1, real h, real d, real x returns real
local real A = (2*(y0+y1)-4*h)/(d*d)
local real B = (y1-y0-A*d*d)/d
return A*x*x + B*x + y0
endfunction
private function GetDist takes real x1, real y1, real x2, real y2 returns real
return SquareRoot(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)))
endfunction
private function Tree_Kill takes nothing returns boolean
local destructable dummy = GetFilterDestructable()
if IsDestructableTree(dummy) then
call KillDestructable(dummy)
endif
set dummy = null
return false
endfunction
/**************************************************************************************
* *
* ARROWS MOVEMENT *
* *
**************************************************************************************/
private struct Fire
private static unit array dummy /*Dummy*/
private static unit array sDummy /*Slow dummy*/
private static player array owner /*Dummy owner*/
private static real array targetx /*Spell Target X*/
private static real array targety /*Spell Target Y*/
private static real array distance /*Arrows Distance traveled*/
private static real array angle /*Arrows Move angle*/
private static real array speed /*Arrows Move speed*/
private static real array height /*Arrows height*/
private static real array heightDec /*Arrows height decrease*/
private static real array damage /*Arrows damage*/
private static rect array treeRect /*Rect for tree kill*/
private static group array damageGroup /*Group to pick units for damage*/
implement CTL
local unit t /*Damaged unit*/
local unit de /*Death effect dummy*/
local real tx /*Damaged unit X*/
local real ty /*Damaged unit Y*/
local real dx /*Arrow location X*/
local real dy /*Arrow location Y*/
local real mx /*Arrow move location X*/
local real my /*Arrow move location Y*/
local real th /*Target height*/
implement CTLExpire
/*Arrows move*/
set dx = GetUnitX(dummy[this])
set dy = GetUnitY(dummy[this])
set mx = dx + speed[this] * Cos(angle[this])
set my = dy + speed[this] * Sin(angle[this])
/*World bound check*/
if (mx < WorldBounds.maxX and mx > WorldBounds.minX and my < WorldBounds.maxY and my > WorldBounds.minY) then
call SetUnitX(dummy[this], mx)
call SetUnitY(dummy[this], my)
else
set distance[this] = 0
endif
/*Arrows height*/
set height[this] = height[this] - heightDec[this]
call SetUnitFlyHeight(dummy[this], height[this], 0)
set distance[this] = distance[this] - speed[this]
/*Damage*/
call GroupEnumUnitsInRange(damageGroup[this], mx, my, DAMAGE_RANGE, null)
loop
set t = FirstOfGroup(damageGroup[this])
exitwhen t == null
set th = GetUnitFlyHeight(t)
if TargetFilter(t, owner[this]) and height[this] > th - Z_DAMAGE_RANGE and height[this] < th + Z_DAMAGE_RANGE then
call UnitDamageTarget(dummy[this], t, damage[this], false, true, ATTACK_TYPE, DAMAGE_TYPE, null)
/*Slowing damaged units*/
static if SLOW then
if SlowFilter(t, owner[this]) then
call IssueTargetOrder(sDummy[this], "slow", t)
endif
endif
/*Ending arrow move*/
set distance[this] = 0
endif
call GroupRemoveUnit(damageGroup[this], t)
endloop
/*Tree Kill*/
static if DESTROY_TREE then
call SetRect(treeRect[this], mx - DAMAGE_RANGE, my - DAMAGE_RANGE, mx + DAMAGE_RANGE, my + DAMAGE_RANGE)
call EnumDestructablesInRect(treeRect[this],function Tree_Kill,null)
endif
/*Arrow move end*/
if distance[this] <= 0 then
call SetUnitAnimation(dummy[this], F_ANIM)
call UnitApplyTimedLife(dummy[this], 'BTLF', 0.75)
/*Arrows death effect*/
set de = CreateUnit(owner[this], DUMMY_CODE2, mx, my, angle[this] * bj_RADTODEG)
call SetUnitAnimation(de, F_D_ANIM)
call SetUnitScale(de, F_D_SCALE, 0, 0)
call UnitApplyTimedLife(de, 'BTLF', F_D_LT)
call SetUnitFlyHeight(de, height[this], 0)
call DestroyGroup(damageGroup[this])
call KillUnit(sDummy[this])
set de = null
set sDummy[this] = null
set dummy[this] = null
set owner[this] = null
set damageGroup[this] = null
call destroy()
endif
implement CTLNull
implement CTLEnd
static method onFire takes unit d, player p, integer lvl, real tx, real ty, real dHeight returns nothing
local thistype this = create()
local real AoE = GetAoE(lvl)
local real dx = GetUnitX(d)
local real dy = GetUnitY(d)
local real RT
set dummy[this] = d
set owner[this] = p
/*Arrow destination location*/
set targetx[this] = tx + AoE * Cos(GetRandomReal(0, 360))
set targety[this] = ty + AoE * Sin(GetRandomReal(0, 360))
set angle[this] = Atan2(targety[this] - dy, targetx[this] - dx)
set distance[this] = GetDist(dx, dy, targetx[this], targety[this])
set speed[this] = F_SPEED
set damage[this] = GetDamage(lvl)
set damageGroup[this] = CreateGroup()
/*Calcultaing time needed for arrows reach target location*/
set RT = distance[this] / speed[this]
set RT = RT * 0.031250
/*Calculating height decrease based on arrows time needed to reach target location*/
set height[this] = dHeight
set heightDec[this] = height[this] / (RT / 0.031250)
/*Tree kill rect*/
static if DESTROY_TREE then
set treeRect[this] = Rect(0, 0, 0, 0)
endif
/*Slow apply dummy*/
set sDummy[this] = CreateUnit(owner[this], DUMMY_CODE, dx, dy, 0)
call ShowUnit(sDummy[this], false)
call UnitAddAbility(sDummy[this], SLOW_CODE)
call SetUnitAbilityLevel(sDummy[this], SLOW_CODE, lvl)
endmethod
endstruct
/**************************************************************************************
* *
* ARCHER JUMP + ARROW SPAWN *
* *
**************************************************************************************/
private struct Jump extends array
private static unit array caster /*caster*/
private static player array owner /*caster's owner*/
private static real array cDistance /*Current distance for parabola function*/
private static real array mDistance /*Maximum distance for parabola funcrion*/
private static real array speed /*Caster move speed*/
private static real array angle /*Caster move angle*/
private static real array targetx /*Spell Target X*/
private static real array targety /*Spell Target Y*/
private static integer array spawnCD /*Arrows spawn cooldown*/
private static integer array spawnCCD /*Arrows spawn cooldown*/
private static integer array ammout /*Arrows total ammout*/
private static integer array count /*Arrows current ammout*/
private static integer array animCD /*Caster animation cooldown*/
private static integer array animCCD /*Caster animation cooldown*/
private static integer array level /*Caster ability level*/
implement CTL
local unit d /*Arrow dummy*/
local real cx /*Caster location X*/
local real cy /*Caster location Y*/
local real mx /*Caster move X*/
local real my /*Caster move Y*/
local real crx /*Arrow create X*/
local real cry /*Arrow create Y*/
local real height /*Caster height*/
local integer index = 0 /*For arrows spawn loop*/
implement CTLExpire
/*Caster movement*/
set cx = GetUnitX(caster[this])
set cy = GetUnitY(caster[this])
set mx = cx - speed[this] * Cos(angle[this])
set my = cy - speed[this] * Sin(angle[this])
/*World bound check*/
if (mx < WorldBounds.maxX and mx > WorldBounds.minX and my < WorldBounds.maxY and my > WorldBounds.minY) then
call SetUnitX(caster[this], mx)
call SetUnitY(caster[this], my)
endif
/*Caster height*/
set height = ParabolaZ2(0, 0, MAX_HEIGHT, mDistance[this], cDistance[this])
call SetUnitFlyHeight(caster[this], height, 0)
/*Distance traveled*/
set cDistance[this] = cDistance[this] + speed[this]
/*Shooting arrows*/
if cDistance[this] > S_DISTANCE and count[this] < ammout[this] then
/*Reducing move speed*/
set speed[this] = S_SPEED
set spawnCCD[this] = spawnCCD[this] + 1
set animCCD[this] = animCCD[this] + 1
/*Caster's animation*/
if animCCD[this] == animCD[this] then
call SetUnitAnimation(caster[this], S_ANIM)
set animCCD[this] = animCCD[this] - animCD[this]
endif
/*Arrows spawn*/
if spawnCCD[this] == spawnCD[this] then
loop
set crx = cx + S_CREATE_OFF * Cos(angle[this])
set cry = cy + S_CREATE_OFF * Sin(angle[this])
set d = CreateUnit(owner[this], DUMMY_CODE, crx, cry, angle[this] * bj_RADTODEG)
/*Arrow move struct call*/
call Fire.onFire(d, owner[this], level[this], targetx[this], targety[this], height + S_HEIGHT)
call SetUnitFlyHeight(d, height + S_HEIGHT, 0)
call SetUnitScale(d, S_SCALE, 0, 0)
/*Calculating ammout of arrows shooted*/
set count[this] = count[this] + 1
set index = index + 1
exitwhen index == S_AMMOUT or count[this] == ammout[this]
set d = null
endloop
set spawnCCD[this] = 0
endif
else
/*Changing speed to norma*/
set speed[this] = SPEED
endif
/*Jump end*/
if cDistance[this] >= mDistance[this] then
call SetUnitFlyHeight(caster[this], 0, 0)
call PauseUnit(caster[this], false)
set caster[this] = null
set owner[this] = null
call destroy()
endif
implement CTLNull
implement CTLEnd
private static method onCast takes nothing returns nothing
local thistype this = create()
local real cx
local real cy
set caster[this] = GetTriggerUnit()
set owner[this] = GetTriggerPlayer()
set level[this] = GetUnitAbilityLevel(caster[this], SPELL_CODE)
set cx = GetUnitX(caster[this])
set cy = GetUnitY(caster[this])
set targetx[this] = GetSpellTargetX()
set targety[this] = GetSpellTargetY()
set mDistance[this] = DISTANCE
set cDistance[this] = 0
set speed[this] = SPEED
set count[this] = 0
set ammout[this] = GetArrows(level[this])
set animCD[this] = S_ANIM_CD
set animCCD[this] = 0
set spawnCD[this] = S_SPAWN_CD
set spawnCCD[this] = 0
set angle[this] = Atan2(targety[this] - cy, targetx[this] - cx)
/*Crow ability for caster's fly*/
if UnitAddAbility(caster[this], CROW_CODE) then
call UnitRemoveAbility(caster[this], CROW_CODE)
endif
/*Caster pause - rly need it*/
call PauseUnit(caster[this], true)
endmethod
/*Init method*/
private static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(SPELL_CODE,function thistype.onCast)
endmethod
endstruct
endscope
//TESH.scrollpos=9
//TESH.alwaysfold=0
library CTL /* v1.1.0.0
*************************************************************************************
*
* CTL or Constant Timer Loop provides a loop for constant merged timers of timeout .03125
*
* Similar to T32 but pauses timer when no structs have instances and removes structs
* from timer trigger when those structs have no instances.
*
* This can also create new timers after destroying a previous timer and generates less
* code in the module. It also generates no triggers so long as the module is implemented
* at the top of the struct.
*
************************************************************************************
*
* static method create takes nothing returns thistype
* - CTL
* - Creates new timer
*
* method destroy takes nothing returns nothing
* - CTL
* - Destroys created timer
*
* Module
*
* module CTL
* - Declare locals in here
* - Run ini code
* module CTLExpire
* - Run timer code
* -
* - thistype this refers to current expiring timer\
* module CTLNull
* - Null locals here
* module CTLEnd
*
* Example of Constant Timer Loop 32
* struct MyTimer extends array
* integer myValue
* implement CTL
* local string s="My value is "
* implement CTLExpire
* call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,s+I2S(myValue))
* call destroy()
* implement CTLNull
* set s=null //pointless, but shows how to use null block
* implement CTLEnd
* endstruct
*
* set MyTimer.create().myValue=16 //will display "My value is 16" in 5 seconds
*
* module CT32
* - A constant running timer. Useful when the timer is pretty much never ever
* - going to stop. Also allows control over loop (just provides an expiring timer).
* - Code goes in between two methods
* module CT32End
*
* Example of Constant Timer 32
*
* //Displays
* // 1
* // 2
* // 3
* struct MyTimers extends array
* integer myValue
* thistype next
* implement CTL2
* local thistype this=thistype(0).next
* loop
* exitwhen 0==this
* call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,s+I2S(myValue))
* set this=next
* endloop
* implement CTL2End
* private static method onInit takes nothing returns nothing
* set thistype(0).next=1
* set thistype(1).next=2
* set thistype(2).next=3
* set thistype(1).myValue=1
* set thistype(2).myValue=2
* set thistype(3).myValue=3
* endmethod
* endstruct
*
************************************************************************************/
globals
private integer ic=0 //instance count
private integer tc=0 //timer count
private integer array rf //root first
private integer array n //next
private integer array p //previous
private integer array th //timer head
private integer array ns //next stack
private trigger t=CreateTrigger()
private timer m=CreateTimer()
private triggercondition array ct
private conditionfunc array rc
endglobals
private function E takes nothing returns nothing
local integer i=ns[0]
set ns[0]=0
loop
exitwhen 0==i
if (0==p[i]) then
if (0==n[i]) then
call TriggerRemoveCondition(t,ct[th[i]])
set ct[th[i]]=null
set tc=tc-1
set rf[th[i]]=0
else
set rf[th[i]]=n[i]
set p[n[i]]=0
endif
else
set p[n[i]]=p[i]
set n[p[i]]=n[i]
endif
set n[i]=n[0]
set n[0]=i
set i=ns[i]
endloop
if (0==tc) then
call PauseTimer(m)
else
call TriggerEvaluate(t)
endif
endfunction
private function CT takes integer r returns integer
local integer i
local integer f
if (0==n[0]) then
set i=ic+1
set ic=i
else
set i=n[0]
set n[0]=n[i]
endif
set th[i]=r
set ns[i]=-1
set f=rf[r]
if (0==f) then
set n[i]=0
set p[i]=0
set rf[r]=i
set ct[r]=TriggerAddCondition(t,rc[r])
if (0==tc) then
call TimerStart(m,.031250000,true,function E)
endif
set tc=tc+1
else
set n[i]=f
set p[i]=0
set p[f]=i
set rf[r]=i
endif
return i
endfunction
private function DT takes integer t returns nothing
debug if (0>ns[t]) then
set ns[t]=ns[0]
set ns[0]=t
debug else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"TIMER LOOP ERROR: ATTEMPT TO DESTROY NULL TIMER")
debug endif
endfunction
private keyword r
private keyword e
module CTL
static integer r
static method create takes nothing returns thistype
return CT(r)
endmethod
method destroy takes nothing returns nothing
call DT(this)
endmethod
static method e takes nothing returns boolean
local thistype this=rf[r]
endmodule
module CTLExpire
loop
exitwhen 0==this
endmodule
module CTLNull
set this=n[this]
endloop
endmodule
module CTLEnd
return false
endmethod
private static method onInit takes nothing returns nothing
set r=ic+1
set ic=r
set rc[r]=Condition(function thistype.e)
endmethod
endmodule
module CT32
static method e takes nothing returns boolean
endmodule
module CT32End
return false
endmethod
private static method onInit takes nothing returns nothing
call TriggerAddCondition(t,Condition(function thistype.e))
if (0==tc) then
call TimerStart(m,.031250000,true,function E)
endif
set tc=tc+1
endmethod
endmodule
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library IsDestructableTree initializer init /* v1.2
*************************************************************************************
*
* Detect whether a destructable is a tree or not.
*
***************************************************************************
*
* Credits
*
* To PitzerMike
* -----------------------
*
* for IsDestructableTree
*
*************************************************************************************
*
* Functions
*
* function IsDestructableTree takes destructable which returns boolean
*
* function IsDestructableAlive takes destructable which returns boolean
*
* function IsDestructableDead takes destructable which returns boolean
*
* function IsTreeAlive takes destructable which returns boolean
* - May only return true for trees
*
* function KillTree takes destructable which returns nothing
* - May only kill trees
*
*/
globals
private constant integer UNIT_DUMMY_HARVESTER = 'hpea'//human peasant
private constant integer HARVEST_ABILITY = 'Ahrl'//ghoul harvest
private constant integer HARVEST = 0xD0032//harvest order, could also be 852018
private constant player PLAYER_OWNER = Player(PLAYER_NEUTRAL_PASSIVE)
private unit HARVESTER = null
endglobals
function IsDestructableTree takes destructable d returns boolean
debug if (d == null) then
debug call BJDebugMsg("ERROR: library IsDestructableTree, function IsDestructableTree, INVALID DESTRUCTABLE")
debug return false
debug endif
//851973 is the order id for stunned, it will interrupt the preceding harvest order.
return (IssueTargetOrderById(HARVESTER, HARVEST, d)) and (IssueImmediateOrderById(HARVESTER, 851973))
endfunction
function IsDestructableAlive takes destructable d returns boolean
return (GetWidgetLife(d) > 0.405)
endfunction
function IsTreeAlive takes destructable d returns boolean
return IsDestructableAlive(d) and IsDestructableTree(d)
endfunction
function KillTree takes destructable d returns nothing
if IsTreeAlive(d) then
call KillDestructable(d)
endif
endfunction
function IsDestructableDead takes destructable d returns boolean
return (GetWidgetLife(d) <= 0.405)
endfunction
private function init takes nothing returns nothing
set HARVESTER=CreateUnit(PLAYER_OWNER,UNIT_DUMMY_HARVESTER,0,0,0)
call UnitAddAbility(HARVESTER, HARVEST_ABILITY)
call UnitAddAbility(HARVESTER, 'Aloc')
call ShowUnit(HARVESTER, false)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
//============================================================================
// SpellEffectEvent
// - Version 1.1.0.0
//
// API
// ---
// RegisterSpellEffectEvent(integer abil, code onCast)
//
// Requires
// --------
// RegisterPlayerUnitEvent: hiveworkshop.com/forums/showthread.php?t=203338
//
// Optional
// --------
// Table: hiveworkshop.com/forums/showthread.php?t=188084
//
library SpellEffectEvent requires RegisterPlayerUnitEvent, optional Table
//============================================================================
private module M
static if LIBRARY_Table then
static Table tb
else
static hashtable ht = InitHashtable()
endif
static method onCast takes nothing returns nothing
static if LIBRARY_Table then
call TriggerEvaluate(.tb.trigger[GetSpellAbilityId()])
else
call TriggerEvaluate(LoadTriggerHandle(.ht, 0, GetSpellAbilityId()))
endif
endmethod
private static method onInit takes nothing returns nothing
static if LIBRARY_Table then
set .tb = Table.create()
endif
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function thistype.onCast)
endmethod
endmodule
//============================================================================
private struct S extends array
implement M
endstruct
//============================================================================
function RegisterSpellEffectEvent takes integer abil, code onCast returns nothing
static if LIBRARY_Table then
if not S.tb.handle.has(abil) then
set S.tb.trigger[abil] = CreateTrigger()
endif
call TriggerAddCondition(S.tb.trigger[abil], Filter(onCast))
else
if not HaveSavedHandle(S.ht, 0, abil) then
call SaveTriggerHandle(S.ht, 0, abil, CreateTrigger())
endif
call TriggerAddCondition(LoadTriggerHandle(S.ht, 0, abil), Filter(onCast))
endif
endfunction
endlibrary
//TESH.scrollpos=12
//TESH.alwaysfold=0
/**************************************************************
*
* RegisterPlayerUnitEvent
* v5.1.0.1
* By Magtheridon96
*
* I would like to give a special thanks to Bribe, azlier
* and BBQ for improving this library. For modularity, it only
* supports player unit events.
*
* Functions passed to RegisterPlayerUnitEvent must either
* return a boolean (false) or nothing. (Which is a Pro)
*
* Warning:
* --------
*
* - Don't use TriggerSleepAction inside registered code.
* - Don't destroy a trigger unless you really know what you're doing.
*
* API:
* ----
*
* - function RegisterPlayerUnitEvent takes playerunitevent whichEvent, code whichFunction returns nothing
* - Registers code that will execute when an event fires.
* - function RegisterPlayerUnitEventForPlayer takes playerunitevent whichEvent, code whichFunction, player whichPlayer returns nothing
* - Registers code that will execute when an event fires for a certain player.
* - function GetPlayerUnitEventTrigger takes playerunitevent whichEvent returns trigger
* - Returns the trigger corresponding to ALL functions of a playerunitevent.
*
**************************************************************/
library RegisterPlayerUnitEvent // Special Thanks to Bribe and azlier
globals
private trigger array t
endglobals
function RegisterPlayerUnitEvent takes playerunitevent p, code c returns nothing
local integer i = GetHandleId(p)
local integer k = 15
if t[i] == null then
set t[i] = CreateTrigger()
loop
call TriggerRegisterPlayerUnitEvent(t[i], Player(k), p, null)
exitwhen k == 0
set k = k - 1
endloop
endif
call TriggerAddCondition(t[i], Filter(c))
endfunction
function RegisterPlayerUnitEventForPlayer takes playerunitevent p, code c, player pl returns nothing
local integer i = 16 * GetHandleId(p) + GetPlayerId(pl)
if t[i] == null then
set t[i] = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(t[i], pl, p, null)
endif
call TriggerAddCondition(t[i], Filter(c))
endfunction
function GetPlayerUnitEventTrigger takes playerunitevent p returns trigger
return t[GetHandleId(p)]
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library_once WorldBounds /* v2.0.0.0
************************************************************************************
*
* struct WorldBounds extends array
* readonly static integer maxX
* readonly static integer maxY
* readonly static integer minX
* readonly static integer minY
* readonly static integer centerX
* readonly static integer centerY
* readonly static rect world
* readonly static region worldRegion
*
************************************************************************************/
private module WorldBoundInit
private static method onInit takes nothing returns nothing
set world=GetWorldBounds()
set maxX=R2I(GetRectMaxX(world))
set maxY=R2I(GetRectMaxY(world))
set minX=R2I(GetRectMinX(world))
set minY=R2I(GetRectMinY(world))
set centerX=R2I((maxX+minX)/2)
set centerY=R2I((minY+maxY)/2)
set worldRegion=CreateRegion()
call RegionAddRect(worldRegion,world)
endmethod
endmodule
struct WorldBounds extends array
readonly static integer maxX
readonly static integer maxY
readonly static integer minX
readonly static integer minY
readonly static integer centerX
readonly static integer centerY
readonly static rect world
readonly static region worldRegion
implement WorldBoundInit
endstruct
endlibrary