Name | Type | is_array | initial_value |
//TESH.scrollpos=52
//TESH.alwaysfold=0
scope FrostWyrm //version 1.1
/*---------------------------------------------------------------------------------------------------------
*
* Requires:
*
*-----------------------------------------------------------------------------------------------------------
*
* - CTL [By Nestharus]
* - WorldBounds [By Nestharus]
* - IsDestructableTree [By PitzerMike]
* - SpellEffectEvent [By Bribe]
* - RegisterPlayerUnitEvent [By Magtheridon9]
*
*-----------------------------------------------------------------------------------------------------------
*
* How to import:
*
*-----------------------------------------------------------------------------------------------------------
*
* - Copy Frost wyrm Ability from object editor ---> Abilities
* - Copy Frost wyrm (Freeze) Ability from objest editor ---> Abilities
* - Copy Frost wyrm (Freeze) Buff from object editor ---> Buffs/Effects
* - Copy Frost wyrm - Dummy 1 from objedt editor ---> Units
* - Copy Frost wyrm - Dummy 2 from object editor ---> Units
* - Copy Frost wyrm Trigger from Trigger editor
* - Copy Libraries folder from Trigger editor
*
* - In object editor --> Abilities go to Frost wyrm (freeze) ability and set Buffs to Frost wyrm (Freeze)
*
*-----------------------------------------------------------------------------------------------------------
*
* Changelog:
*
*-----------------------------------------------------------------------------------------------------------
*
* v1.0
* - First release.
* v1.01
* - Remade Tree_Kill function
* - Fixed unit group leak
* - No longer nulling players
* - Changed dummies names
*
*-----------------------------------------------------------------------------------------------------------*/
/***********************************************************************************
* *
* CONFIGURATION *
* *
***********************************************************************************/
globals
/*Ability and dummies rawcodes*/
/*******************************************************************************/
/**/ /**/
/**/ private constant integer SPELL_CODE = 'A000' /**/ /*Main Ability rawcode*/
/**/ private constant integer FREEZE_CODE = 'A001' /**/ /*Freeze ability rawcode*/
/**/ private constant integer WYRM_CODE = 'h000' /**/ /*Frost wyrm - Dummy 1 rawcode*/
/**/ private constant integer BREATH_CODE = 'h003' /**/ /*Frost wyrm - Dummy 2 rawcode*/
/**/ /**/
/*******************************************************************************/
/*Frost wyrm configuration*/
//Frost wyrm scale
private constant real WYRM_SCALE = 1
//Frost wyrm spawn height
private constant real WYRM_HEIGHT_START = 800
//Frost wyrm destination height. Once it will get on this height it will not fly lower.
private constant real WYRM_HEIGHT = 450
//Time at which forst wyrm will reach WYRM_HEIGHT. If you will se too high like
//3.0 frost wyrm will never reach WYRM_HEIGHT so it will just keep going lower.
private constant real WYRM_HEIGHT_TIME = 3.0
//Frost wyrm will not spawn on caster, it will spawn back by this distance
private constant real WYRM_CREATE_OFF = 400
//Frost wyrm will start it's animation once he will travel this distance
private constant real WYRM_ANIM_DISTANCE = 175
//Frost wyrm animation used for breath
private constant string WYRM_ANIMATION = "attack"
/*Frost breath configuration*/
//Cooldown between creating another one dummy for frost breath. At this
//moment it's 2 * 0.031250
private constant integer BREATH_CD = 2
//To make dummie spawn from wyrm's head not from chest i set this distance
private constant real BREATH_CREATE_OFF = 125
//Frost wyrm will start breating after it will travel this distance
private constant real BREATH_START = 400
//Breath dummies scale
private constant real BREATH_SCALE = 1
//Bretah dummies start height
private constant real BREATH_HEIGHT = 400
//Time at which breat dummies reach the BREATH_LAND_HEIGHT
private constant real BREATH_LAND_TIME = 0.25
//When breath dummies will get on it or lower height they will explode
private constant real BREATH_LAND_HEIGHT = 20
//Breath dummies scale when they land on the ground to make effect bigger
private constant real BREATH_DEATH_SCALE = 1.8
//Bretah dummies nimation played when they land on the ground
private constant string BREATH_ANIM = "death"
//We stop frost wyrm after this time/ 1 = 0.031250
private constant integer BREATH_ANIM_STOP = 28
/*Move speeds configuration*/
//Wyrm movement speed before breathing
private constant real MOVE_SPEED_FIRST = 600
//Wyrm movement speed when it is breating
private constant real MOVE_SPEED_SECOND = 300
/*Damage configuraton*/
//Damage range
private constant real DAMAGE_RANGE = 100
//Attack type
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_MAGIC
//Damage type
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_DEATH
/*Booleans*/
//Should forst breath kill tress?
private constant boolean DESTROY_TREE = true
//Should frost breath also freeze enemy units?
private constant boolean FREEZE = true
/*Don't touch*/
//Dummy used to freeze targets
private unit FREEZE_DUMMY
endglobals
/*Function to calculate damage dealt to every unit*/
private function GetDamage takes integer level returns real
return level * 3.00
endfunction
/*Function to calculate distancetravaled by wyrm once he start breathing*/
private function GetDistance takes integer level returns real
return level * 50.00 + 650.00
endfunction
/*Which units should not be damaged*/
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_FLYING)
endfunction
/*Which units should not be freezed*/
private function FreezeFilter takes unit u, player p returns boolean
return IsUnitEnemy(u, p) and not IsUnitType(u, UNIT_TYPE_DEAD) and not IsUnitType(u, UNIT_TYPE_FLYING) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)
endfunction
/***********************************************************************************
* *
* CONFIGURATION END *
* *
***********************************************************************************/
private function Tree_Kill takes nothing returns boolean
call KillTree(GetFilterDestructable())
return false
endfunction
/***********************************************************************************
* *
* FROST BREATH DUMMIES MOVEMENT *
* *
***********************************************************************************/
private struct FrostBreath extends array
private static unit array dummy
private static player array owner
private static real array damage
private static real array height
private static real array heightDec
private static integer array level
static group array ignoreGroup
static group damageGroup
static rect treeRect
implement CTL
local unit t
local real dx
local real dy
implement CTLExpire
set dx = GetUnitX(dummy[this])
set dy = GetUnitY(dummy[this])
set height[this] = height[this] - heightDec[this]
call SetUnitFlyHeight(dummy[this], height[this], 0)
if height[this] <= BREATH_LAND_HEIGHT then
call GroupEnumUnitsInRange(damageGroup, dx, dy, DAMAGE_RANGE, null)
loop
set t = FirstOfGroup(damageGroup)
exitwhen t == null
if TargetFilter(t, owner[this]) and not IsUnitInGroup(t, ignoreGroup[this]) then
call UnitDamageTarget(dummy[this], t, damage[this], true, true, ATTACK_TYPE, DAMAGE_TYPE, null)
call GroupAddUnit(ignoreGroup[this], t)
static if FREEZE then
if FreezeFilter(t, owner[this]) then
call SetUnitAbilityLevel(FREEZE_DUMMY, FREEZE_CODE, level[this])
call IssueTargetOrder(FREEZE_DUMMY, "thunderbolt", t)
endif
endif
endif
call GroupRemoveUnit(damageGroup, t)
endloop
call DestroyGroup(damageGroup)
call DestroyGroup(ignoreGroup[this])
static if DESTROY_TREE then
call SetRect(treeRect, dx - DAMAGE_RANGE, dy - DAMAGE_RANGE, dx + DAMAGE_RANGE, dy + DAMAGE_RANGE)
call EnumDestructablesInRect(treeRect,function Tree_Kill,null)
endif
call SetUnitScale(dummy[this], BREATH_DEATH_SCALE, 0, 0)
call SetUnitAnimation(dummy[this], BREATH_ANIM)
call UnitApplyTimedLife(dummy[this], 'BTLF', 0.75)
set dummy[this] = null
call destroy()
endif
implement CTLNull
implement CTLEnd
static method onBreath takes unit d, player p, integer l, real h returns nothing
local thistype this = create()
set dummy[this] = d
set owner[this] = p
set level[this] = l
set damage[this] = GetDamage(l)
set height[this] = h
set heightDec[this] = height[this] / (BREATH_LAND_TIME * 32)
set damageGroup = CreateGroup()
set ignoreGroup[this] = CreateGroup()
static if DESTROY_TREE then
set treeRect = Rect(0, 0, 0, 0)
endif
endmethod
endstruct
/***********************************************************************************
* *
* FROST WYRM MOVEMENT *
* *
***********************************************************************************/
private struct FrostWyrm extends array
private static unit array caster
private static unit array wyrm
private static player array owner
private static real array angle
private static real array fSpeed
private static real array sSpeed
private static real array fDistance
private static real array sDistance
private static real array cDistance
private static real array wyrmHeight
private static real array wyrmHeightDec
private static integer array level
private static integer array breathCD
private static integer array breathCCD
private static integer array breathStop
private static boolean array wyrmBreath
private static boolean array wyrmAnimation
implement CTL
local unit d
local real dx
local real dy
local real mx
local real my
local real crx
local real cry
implement CTLExpire
set dx = GetUnitX(wyrm[this])
set dy = GetUnitY(wyrm[this])
if wyrmBreath[this] then
set crx = dx + BREATH_CREATE_OFF * Cos(angle[this])
set cry = dy + BREATH_CREATE_OFF * Sin(angle[this])
if breathCCD[this] == breathCD[this] then
set d = CreateUnit(owner[this], BREATH_CODE, crx, cry, angle[this] * bj_RADTODEG)
call SetUnitScale(d, BREATH_SCALE, 0, 0)
call SetUnitFlyHeight(d, wyrmHeight[this], 0)
call FrostBreath.onBreath(d, owner[this], level[this], wyrmHeight[this])
set breathCCD[this] = breathCCD[this] - breathCD[this]
endif
set breathCCD[this] = breathCCD[this] + 1
endif
if fDistance[this] > 0 then
set mx = dx + fSpeed[this] * Cos(angle[this])
set my = dy + fSpeed[this] * Sin(angle[this])
if (mx < WorldBounds.maxX and mx > WorldBounds.minX and my < WorldBounds.maxY and my > WorldBounds.minY) then
call SetUnitX(wyrm[this], mx)
call SetUnitY(wyrm[this], my)
endif
set cDistance[this] = cDistance[this] + fSpeed[this]
set fDistance[this] = fDistance[this] - fSpeed[this]
if cDistance[this] >= WYRM_ANIM_DISTANCE and wyrmAnimation[this] then
call SetUnitAnimation(wyrm[this], WYRM_ANIMATION)
set wyrmAnimation[this] = false
endif
else
if sDistance[this] > 0 then
set mx = dx + sSpeed[this] * Cos(angle[this])
set my = dy + sSpeed[this] * Sin(angle[this])
if (mx < WorldBounds.maxX and mx > WorldBounds.minX and my < WorldBounds.maxY and my > WorldBounds.minY) then
call SetUnitX(wyrm[this], mx)
call SetUnitY(wyrm[this], my)
endif
set cDistance[this] = cDistance[this] + sSpeed[this]
set sDistance[this] = sDistance[this] - sSpeed[this]
else
call SetUnitTimeScale(wyrm[this], 1)
call SetUnitAnimation(wyrm[this], "death")
call UnitApplyTimedLife(wyrm[this], 'BTLF', 1.00)
set caster[this] = null
set wyrm[this] = null
call destroy()
endif
endif
if wyrmHeight[this] > WYRM_HEIGHT then
set wyrmHeight[this] = wyrmHeight[this] - wyrmHeightDec[this]
call SetUnitFlyHeight(wyrm[this], wyrmHeight[this], 0)
endif
set breathStop[this] = breathStop[this] - 1
if breathStop[this] == 0 then
call SetUnitTimeScale(wyrm[this], 0)
endif
if cDistance[this] >= BREATH_START then
set wyrmBreath[this] = true
endif
set d = null
implement CTLNull
implement CTLEnd
private static method onCast takes nothing returns nothing
local thistype this = create()
local real cx
local real cy
local real tx
local real ty
local real crx
local real cry
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 tx = GetSpellTargetX()
set ty = GetSpellTargetY()
set angle[this] = Atan2(ty - cy, tx - cx)
set crx = cx - WYRM_CREATE_OFF * Cos(angle[this])
set cry = cy - WYRM_CREATE_OFF * Sin(angle[this])
set wyrm[this] = CreateUnit(owner[this], WYRM_CODE, crx, cry, angle[this] * bj_RADTODEG)
call SetUnitScale(wyrm[this], WYRM_SCALE, 0, 0)
call SetUnitFlyHeight(wyrm[this], WYRM_HEIGHT_START, 0)
set fDistance[this] = WYRM_CREATE_OFF
set sDistance[this] = GetDistance(level[this])
set fSpeed[this] = MOVE_SPEED_FIRST * 0.031250
set sSpeed[this] = MOVE_SPEED_SECOND * 0.031250
set wyrmAnimation[this] = true
set cDistance[this] = 0
set breathCD[this] = BREATH_CD
set breathCCD[this] = BREATH_CD
set breathStop[this] = BREATH_ANIM_STOP
set wyrmBreath[this] = false
set wyrmHeight[this] = WYRM_HEIGHT_START
set wyrmHeightDec[this] = (WYRM_HEIGHT_START - WYRM_HEIGHT) / (WYRM_HEIGHT_TIME * 32)
endmethod
private static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(SPELL_CODE,function thistype.onCast)
set FREEZE_DUMMY = CreateUnit(Player(0), WYRM_CODE, 0, 0, 0)
call ShowUnit(FREEZE_DUMMY, false)
call UnitAddAbility(FREEZE_DUMMY, FREEZE_CODE)
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=36
//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