Name | Type | is_array | initial_value |
//TESH.scrollpos=145
//TESH.alwaysfold=0
//: §§ ----------------------------------------------------------------------------------------- §§
//: ||
//: || CustomFilter
//: || ################
//: || by Anachron
//: || 07.03.2010 20:24
//: || v. 0.0.1
//: ||
//: || Advanced filtering engine that provides you with cool, new and easy functions that
//: || can become very handy and useable.
//: ||
//: || $ Misc
//: || ---------
//: || Have fun.
//: ||
//: §§ ----------------------------------------------------------------------------------------- §§
library CustomFilter initializer init
private function interface onFilterEvent takes nothing returns nothing
private function interface Cond takes nothing returns boolean
private keyword CustomFilter
private keyword BoolFilter
globals
//: You can use this to return true/false everytime on a filter
BoolFilter TRUE_FILTER = 0
BoolFilter FALSE_FILTER = 0
//: A boolean whether to show or hide enumeration info
//: This helps you whether to see if its working or not.
private constant boolean SHOW_ENUM = true
group FILTER_GROUP = CreateGroup()
private hashtable FilterData = InitHashtable()
endglobals
private struct CustomFilter
public boolean negate = false
private stub method validate takes nothing returns boolean
return true
endmethod
public method filterValidate takes nothing returns boolean
if .negate then
return not.validate()
endif
return .validate()
endmethod
private stub method onPrepare takes nothing returns nothing
endmethod
public stub method prepare takes nothing returns nothing
call .onPrepare()
endmethod
endstruct
struct AndFilter extends CustomFilter
private CustomFilter filterOne = 0
private CustomFilter filterTwo = 0
public static method create takes CustomFilter f1, CustomFilter f2, boolean neg returns thistype
local thistype this = thistype.allocate()
set .filterOne = f1
set .filterTwo = f2
set .negate = neg
return this
endmethod
public method onPrepare takes nothing returns nothing
call .filterOne.prepare()
call .filterOne.prepare()
endmethod
private method validate takes nothing returns boolean
return .filterOne.filterValidate() and .filterTwo.filterValidate()
endmethod
endstruct
struct OrFilter extends CustomFilter
private CustomFilter filterOne = 0
private CustomFilter filterTwo = 0
public static method create takes CustomFilter f1, CustomFilter f2, boolean neg returns thistype
local thistype this = thistype.allocate()
set .filterOne = f1
set .filterTwo = f2
set .negate = neg
return this
endmethod
private method onPrepare takes nothing returns nothing
call .filterOne.prepare()
call .filterTwo.prepare()
endmethod
private method validate takes nothing returns boolean
return .filterOne.filterValidate() or .filterTwo.filterValidate()
endmethod
endstruct
struct LimitedFilter extends CustomFilter
private CustomFilter filter = 0
private integer amount = 0
private integer max = 0
public static method create takes CustomFilter fi, integer m returns thistype
local thistype this = thistype.allocate()
set .filter = fi
set .max = m
return this
endmethod
private method validate takes nothing returns boolean
local boolean valid = .filter.filterValidate()
if .amount < .max and valid then
set .amount = .amount +1
return true
endif
return false
endmethod
private method onPrepare takes nothing returns nothing
call .filter.prepare()
set .amount = 0
endmethod
endstruct
struct BoolFilter extends CustomFilter
public static method create takes boolean b returns thistype
local thistype this = thistype.allocate()
set .negate = b
return this
endmethod
endstruct
//! textmacro CustomFilter_createFilter takes CONST, NAME, TYPE, FTYPE
globals
private CustomFilter $NAME$Filter = TRUE_FILTER
private onFilterEvent on$NAME$Event = 0
$TYPE$ FILTER_$CONST$ = null
endglobals
private function filter$NAME$ takes nothing returns boolean
local boolean hasEnumed = false
set FILTER_$CONST$ = GetFilter$NAME$()
if not HaveSavedInteger(FilterData, $FTYPE$, GetHandleId(FILTER_$CONST$)) then
call SaveInteger(FilterData, $FTYPE$, GetHandleId(FILTER_$CONST$), -1)
else
return false
endif
if FILTER_$CONST$ == null then
debug call BJDebugMsg("|cffffcc00" + SCOPE_PREFIX + "$NAME$" + "_Error|r: Filter has no valid " + "$TYPE$" + " to process with.")
return false
endif
set hasEnumed = $NAME$Filter.filterValidate()
if hasEnumed then
debug if SHOW_ENUM then
debug call BJDebugMsg("|cffffcc00" + SCOPE_PREFIX + "$CONST$" + "_Notice|r: [Enum] [|cffffcc00" + "$TYPE$" + "|r] " + Get$NAME$Name(FILTER_$CONST$) + "(#" + I2S(GetHandleId(FILTER_$CONST$)) + ")")
debug endif
call on$NAME$Event.execute()
endif
return hasEnumed
endfunction
function set$NAME$Filter takes CustomFilter theFilter returns nothing
set $NAME$Filter = theFilter
set on$NAME$Event = 0
call FlushChildHashtable(FilterData, $FTYPE$)
endfunction
function get$NAME$Filter takes nothing returns CustomFilter
return $NAME$Filter
endfunction
function setOn$NAME$Enum takes onFilterEvent theFunc returns nothing
set on$NAME$Event = theFunc
endfunction
function getOn$NAME$Enum takes nothing returns onFilterEvent
return on$NAME$Event
endfunction
globals
boolexpr $CONST$_FILTER = null
endglobals
struct $NAME$CondFilter extends CustomFilter
private CustomFilter filter = 0
private Cond cond = 0
public static method create takes CustomFilter fi, Cond c, boolean neg returns thistype
local thistype this = thistype.allocate()
set .filter = fi
set .cond = c
set .negate = neg
return this
endmethod
private method onPrepare takes nothing returns nothing
call .filter.prepare()
endmethod
private method validate takes nothing returns boolean
if not .cond.evaluate() then
return false
endif
return .filter.filterValidate()
endmethod
endstruct
//! endtextmacro
//! runtextmacro CustomFilter_createFilter("DESTRUCTABLE", "Destructable", "destructable", "0")
//! runtextmacro CustomFilter_createFilter("ITEM", "Item", "item", "1")
//! runtextmacro CustomFilter_createFilter("UNIT", "Unit", "unit", "2")
//! runtextmacro CustomFilter_createFilter("PLAYER", "Player", "player", "3")
//: == § -- -- §
//: Here are my default filters.
//: == § -- -- §
struct UnitTypeFilter extends CustomFilter
private unittype uType = null
public static method create takes unittype t, boolean neg returns thistype
local thistype this = thistype.allocate()
set .uType = t
set .negate = neg
return this
endmethod
private method validate takes nothing returns boolean
return IsUnitType(FILTER_UNIT, .uType)
endmethod
endstruct
struct UnitBuffFilter extends CustomFilter
private integer bType = 0
public static method create takes integer b, boolean neg returns thistype
local thistype this = thistype.allocate()
set .bType = b
set .negate = neg
return this
endmethod
private method validate takes nothing returns boolean
return GetUnitAbilityLevel(FILTER_UNIT, .bType) > 0
endmethod
endstruct
struct RangeFilter extends CustomFilter
private CustomFilter filter = 0
private real distance = 0
private Loc pos = 0
public static method create takes CustomFilter fi, real x, real y, real d, boolean neg returns thistype
local thistype this = thistype.allocate()
set .pos = Loc.create(x, y, 0.)
set .filter = fi
set .distance = d
set .negate = neg
return this
endmethod
private method validate takes nothing returns boolean
local Loc cur = Loc.create(GetUnitX(FILTER_UNIT), GetUnitY(FILTER_UNIT), 0.)
local boolean did = .pos.distanceTo(cur) <= .distance
call cur.destroy()
return did and .filter.filterValidate()
endmethod
endstruct
struct AllyFilter extends CustomFilter
private player allyWith = null
public static method create takes player p, boolean neg returns thistype
local thistype this = thistype.allocate()
set allyWith = p
set .negate = neg
return this
endmethod
private method validate takes nothing returns boolean
return IsPlayerAlly(GetOwningPlayer(FILTER_UNIT), .allyWith)
endmethod
endstruct
//: == § -- -- §
//: Place your filters in this section
//: == § -- -- §
private function init takes nothing returns nothing
set TRUE_FILTER = BoolFilter.create(false)
set FALSE_FILTER = BoolFilter.create(true)
set DESTRUCTABLE_FILTER = Condition(function filterDestructable)
set ITEM_FILTER = Condition(function filterItem)
set UNIT_FILTER = Condition(function filterUnit)
set PLAYER_FILTER = Condition(function filterPlayer)
endfunction
endlibrary
//TESH.scrollpos=13
//TESH.alwaysfold=0
library Loc
//! textmacro Loc_addOperator takes name, type, object
method operator $name$= takes $type$ val returns nothing
set .$object$ = val
endmethod
method operator $name$ takes nothing returns $type$
return .$object$
endmethod
//! endtextmacro
function makeRealAngle takes real a returns real
local real radA = 360. * bj_DEGTORAD
loop
exitwhen a < radA and a >= 0.
if a < 0 then
set a = a + radA
elseif a > radA then
set a = a - radA
endif
endloop
return a
endfunction
struct Loc
private real x = 0.
private real y = 0.
private real z = 0.
//! runtextmacro Loc_addOperator("X", "real", "x")
//! runtextmacro Loc_addOperator("Y", "real", "y")
//! runtextmacro Loc_addOperator("Z", "real", "z")
public static method create takes real x, real y, real z returns thistype
local thistype this = thistype.allocate()
set .x = x
set .y = y
set .z = z
return this
endmethod
public method angleTo takes thistype obj returns real
return makeRealAngle(Atan2(obj.y - .y, obj.x - .x))
endmethod
public method distanceTo takes thistype obj returns real
local real dx = obj.x - .x
local real dy = obj.y - .y
return SquareRoot(dx * dx + dy * dy)
endmethod
public method move takes real d, real f returns nothing
set .x = .x + d * Cos(f)
set .y = .y + d * Sin(f)
endmethod
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library CFLib initializer init requires CustomFilter
globals
UnitTypeFilter FILTER_UNIT_ANCIENT = 0
UnitTypeFilter FILTER_UNIT_ATTACK_AIR = 0
UnitTypeFilter FILTER_UNIT_ATTACK_GROUND = 0
UnitTypeFilter FILTER_UNIT_DEAD = 0
UnitTypeFilter FILTER_UNIT_ETHEREAL = 0
UnitTypeFilter FILTER_UNIT_FLYING = 0
UnitTypeFilter FILTER_UNIT_GIANT = 0
UnitTypeFilter FILTER_UNIT_GROUND = 0
UnitTypeFilter FILTER_UNIT_HERO = 0
UnitTypeFilter FILTER_UNIT_MAGIC_IMMUNE = 0
UnitTypeFilter FILTER_UNIT_MECHANICAL = 0
UnitTypeFilter FILTER_UNIT_MELEE = 0
UnitTypeFilter FILTER_UNIT_PEON = 0
UnitTypeFilter FILTER_UNIT_PLAGUED = 0
UnitTypeFilter FILTER_UNIT_POISONED = 0
UnitTypeFilter FILTER_UNIT_POLYMORPHED = 0
UnitTypeFilter FILTER_UNIT_RANGED = 0
UnitTypeFilter FILTER_UNIT_RESISTANT = 0
UnitTypeFilter FILTER_UNIT_SAPPER = 0
UnitTypeFilter FILTER_UNIT_SLEEPING = 0
UnitTypeFilter FILTER_UNIT_SNARED = 0
UnitTypeFilter FILTER_UNIT_STRUCTURE = 0
UnitTypeFilter FILTER_UNIT_STUNNED = 0
UnitTypeFilter FILTER_UNIT_SUMMONED = 0
UnitTypeFilter FILTER_UNIT_TAUREN = 0
UnitTypeFilter FILTER_UNIT_TOWNHALL = 0
UnitTypeFilter FILTER_UNIT_UNDEAD = 0
UnitTypeFilter FILTER_UNIT_ALIVE = 0
UnitTypeFilter FILTER_UNIT_NOT_ANCIENT = 0
UnitTypeFilter FILTER_UNIT_NOT_ATTACK_AIR = 0
UnitTypeFilter FILTER_UNIT_NOT_ATTACK_GROUND = 0
UnitTypeFilter FILTER_UNIT_AWAKE = 0
UnitTypeFilter FILTER_UNIT_NOT_DEAD = 0
UnitTypeFilter FILTER_UNIT_NOT_ETHEREAL = 0
UnitTypeFilter FILTER_UNIT_NOT_FLYING = 0
UnitTypeFilter FILTER_UNIT_NOT_GIANT = 0
UnitTypeFilter FILTER_UNIT_NOT_GROUND = 0
UnitTypeFilter FILTER_UNIT_NOT_HERO = 0
UnitTypeFilter FILTER_UNIT_NOT_MAGIC_IMMUNE = 0
UnitTypeFilter FILTER_UNIT_NOT_MECHANICAL = 0
UnitTypeFilter FILTER_UNIT_NOT_MELEE = 0
UnitTypeFilter FILTER_UNIT_NOT_PEON = 0
UnitTypeFilter FILTER_UNIT_NOT_PLAGUED = 0
UnitTypeFilter FILTER_UNIT_NOT_POISONED = 0
UnitTypeFilter FILTER_UNIT_NOT_POLYMORPHED = 0
UnitTypeFilter FILTER_UNIT_NOT_RANGED = 0
UnitTypeFilter FILTER_UNIT_NOT_RESISTANT = 0
UnitTypeFilter FILTER_UNIT_NOT_SAPPER = 0
UnitTypeFilter FILTER_UNIT_NOT_SNARED = 0
UnitTypeFilter FILTER_UNIT_NOT_STRUCTURE = 0
UnitTypeFilter FILTER_UNIT_NOT_STUNNED = 0
UnitTypeFilter FILTER_UNIT_NOT_SUMMONED = 0
UnitTypeFilter FILTER_UNIT_NOT_TAUREN = 0
UnitTypeFilter FILTER_UNIT_NOT_TOWNHALL = 0
UnitTypeFilter FILTER_UNIT_NOT_UNDEAD = 0
UnitBuffFilter FILTER_UNIT_HAS_BUFF_ENSNARED = 0
endglobals
private function init takes nothing returns nothing
//: ==----
//: Create the UnitTypeFilters here.
//: UnitTypeFilter.create(UnitType, Negate?)
//: ==----
set FILTER_UNIT_ANCIENT = UnitTypeFilter.create(UNIT_TYPE_ANCIENT, false)
set FILTER_UNIT_ATTACK_AIR = UnitTypeFilter.create(UNIT_TYPE_ATTACKS_FLYING, false)
set FILTER_UNIT_ATTACK_GROUND = UnitTypeFilter.create(UNIT_TYPE_ATTACKS_GROUND, false)
set FILTER_UNIT_DEAD = UnitTypeFilter.create(UNIT_TYPE_DEAD, false)
set FILTER_UNIT_ETHEREAL = UnitTypeFilter.create(UNIT_TYPE_ETHEREAL, false)
set FILTER_UNIT_FLYING = UnitTypeFilter.create(UNIT_TYPE_FLYING, false)
set FILTER_UNIT_GIANT = UnitTypeFilter.create(UNIT_TYPE_GIANT, false)
set FILTER_UNIT_GROUND = UnitTypeFilter.create(UNIT_TYPE_GROUND, false)
set FILTER_UNIT_HERO = UnitTypeFilter.create(UNIT_TYPE_HERO, false)
set FILTER_UNIT_MAGIC_IMMUNE = UnitTypeFilter.create(UNIT_TYPE_MAGIC_IMMUNE, false)
set FILTER_UNIT_MECHANICAL = UnitTypeFilter.create(UNIT_TYPE_MECHANICAL, false)
set FILTER_UNIT_MELEE = UnitTypeFilter.create(UNIT_TYPE_MELEE_ATTACKER, false)
set FILTER_UNIT_PEON = UnitTypeFilter.create(UNIT_TYPE_PEON, false)
set FILTER_UNIT_PLAGUED = UnitTypeFilter.create(UNIT_TYPE_PLAGUED, false)
set FILTER_UNIT_POISONED = UnitTypeFilter.create(UNIT_TYPE_POISONED, false)
set FILTER_UNIT_POLYMORPHED = UnitTypeFilter.create(UNIT_TYPE_POLYMORPHED, false)
set FILTER_UNIT_RANGED = UnitTypeFilter.create(UNIT_TYPE_RANGED_ATTACKER, false)
set FILTER_UNIT_RESISTANT = UnitTypeFilter.create(UNIT_TYPE_RESISTANT, false)
set FILTER_UNIT_SAPPER = UnitTypeFilter.create(UNIT_TYPE_SAPPER, false)
set FILTER_UNIT_SLEEPING = UnitTypeFilter.create(UNIT_TYPE_SLEEPING, false)
set FILTER_UNIT_SNARED = UnitTypeFilter.create(UNIT_TYPE_SNARED, false)
set FILTER_UNIT_STRUCTURE = UnitTypeFilter.create(UNIT_TYPE_STRUCTURE, false)
set FILTER_UNIT_STUNNED = UnitTypeFilter.create(UNIT_TYPE_STUNNED, false)
set FILTER_UNIT_SUMMONED = UnitTypeFilter.create(UNIT_TYPE_SUMMONED, false)
set FILTER_UNIT_TAUREN = UnitTypeFilter.create(UNIT_TYPE_TAUREN, false)
set FILTER_UNIT_TOWNHALL = UnitTypeFilter.create(UNIT_TYPE_TOWNHALL, false)
set FILTER_UNIT_UNDEAD = UnitTypeFilter.create(UNIT_TYPE_UNDEAD, false)
//: ==----
//: Create the negated UnitTypeFilters here.
//: UnitTypeFilter.create(UnitType, Negate?)
//: ==----
set FILTER_UNIT_ALIVE = UnitTypeFilter.create(UNIT_TYPE_DEAD, true)
set FILTER_UNIT_NOT_ANCIENT = UnitTypeFilter.create(UNIT_TYPE_ANCIENT, true)
set FILTER_UNIT_NOT_ATTACK_AIR = UnitTypeFilter.create(UNIT_TYPE_ATTACKS_FLYING, true)
set FILTER_UNIT_NOT_ATTACK_GROUND = UnitTypeFilter.create(UNIT_TYPE_ATTACKS_GROUND, true)
set FILTER_UNIT_AWAKE = UnitTypeFilter.create(UNIT_TYPE_SLEEPING, true)
set FILTER_UNIT_NOT_ETHEREAL = UnitTypeFilter.create(UNIT_TYPE_ETHEREAL, true)
set FILTER_UNIT_NOT_FLYING = UnitTypeFilter.create(UNIT_TYPE_FLYING, true)
set FILTER_UNIT_NOT_GIANT = UnitTypeFilter.create(UNIT_TYPE_GIANT, true)
set FILTER_UNIT_NOT_GROUND = UnitTypeFilter.create(UNIT_TYPE_GROUND, true)
set FILTER_UNIT_NOT_HERO = UnitTypeFilter.create(UNIT_TYPE_HERO, true)
set FILTER_UNIT_NOT_MAGIC_IMMUNE = UnitTypeFilter.create(UNIT_TYPE_MAGIC_IMMUNE, true)
set FILTER_UNIT_NOT_MECHANICAL = UnitTypeFilter.create(UNIT_TYPE_MECHANICAL, true)
set FILTER_UNIT_NOT_MELEE = UnitTypeFilter.create(UNIT_TYPE_MELEE_ATTACKER, true)
set FILTER_UNIT_NOT_PEON = UnitTypeFilter.create(UNIT_TYPE_PEON, true)
set FILTER_UNIT_NOT_PLAGUED = UnitTypeFilter.create(UNIT_TYPE_PLAGUED, true)
set FILTER_UNIT_NOT_POISONED = UnitTypeFilter.create(UNIT_TYPE_POISONED, true)
set FILTER_UNIT_NOT_POLYMORPHED = UnitTypeFilter.create(UNIT_TYPE_POLYMORPHED, true)
set FILTER_UNIT_NOT_RANGED = UnitTypeFilter.create(UNIT_TYPE_RANGED_ATTACKER, true)
set FILTER_UNIT_NOT_RESISTANT = UnitTypeFilter.create(UNIT_TYPE_RESISTANT, true)
set FILTER_UNIT_NOT_SAPPER = UnitTypeFilter.create(UNIT_TYPE_SAPPER, true)
set FILTER_UNIT_NOT_SNARED = UnitTypeFilter.create(UNIT_TYPE_SNARED, true)
set FILTER_UNIT_NOT_STRUCTURE = UnitTypeFilter.create(UNIT_TYPE_STRUCTURE, true)
set FILTER_UNIT_NOT_STUNNED = UnitTypeFilter.create(UNIT_TYPE_STUNNED, true)
set FILTER_UNIT_NOT_SUMMONED = UnitTypeFilter.create(UNIT_TYPE_SUMMONED, true)
set FILTER_UNIT_NOT_TAUREN = UnitTypeFilter.create(UNIT_TYPE_TAUREN, true)
set FILTER_UNIT_NOT_TOWNHALL = UnitTypeFilter.create(UNIT_TYPE_TOWNHALL, true)
set FILTER_UNIT_NOT_UNDEAD = UnitTypeFilter.create(UNIT_TYPE_UNDEAD, true)
//: ==----
//: Create the UnitBuffFilters here.
//: UnitBuffFilter.create(BuffID, Negate?)
//: ==----
set FILTER_UNIT_HAS_BUFF_ENSNARED = UnitBuffFilter.create('esnr', false)
endfunction
endlibrary
//TESH.scrollpos=29
//TESH.alwaysfold=0
library CFEnum requires CustomFilter, Loc
globals
//: The update interval of line enumeration.
//: You shouldn't use a lower value then 32.
private constant real LINE_UPDATE = 64.
endglobals
function EnumUnitsOfPlayer takes group theGroup, player thePlayer returns nothing
call GroupEnumUnitsOfPlayer(theGroup, thePlayer, UNIT_FILTER)
endfunction
function EnumUnitsInRange takes group theGroup, real x, real y, real r returns nothing
call GroupEnumUnitsInRange(theGroup, x, y, r, UNIT_FILTER)
endfunction
function EnumUnitsInRect takes group theGroup, rect theRect returns nothing
call GroupEnumUnitsInRect(theGroup, theRect, UNIT_FILTER)
endfunction
function EnumUnitsOfPlayersInForce takes group theGroup, force theForce returns nothing
local integer i = 0
loop
exitwhen i >= bj_MAX_PLAYERS
if IsPlayerInForce(Player(i), theForce) then
call EnumUnitsOfPlayer(theGroup, Player(i))
endif
set i = i +1
endloop
endfunction
//: This enumerates all units that are in range r of the line between Loc(x1, y1) - Loc(x2, y2)
//: .----------------.
//: n / p \
//: \ p /
//: .----------------.
//: n
//: n = not picked
//: p = picked
//: enumGroup PosX PosY PosX2 PosY2 radius
function EnumUnitsInRangeOfLine takes group theGroup, real x1, real y1, real x2, real y2, real r returns nothing
local Loc cur = Loc.create(x1, y1, 0.)
local Loc end = Loc.create(x2, y2, 0.)
local real face = cur.angleTo(end)
local integer i = R2I(cur.distanceTo(end) / LINE_UPDATE)
loop
exitwhen i <= 0
call EnumUnitsInRange(theGroup, cur.X, cur.Y, r)
call cur.move(LINE_UPDATE, face)
set i = i -1
endloop
call cur.destroy()
call end.destroy()
endfunction
//: This enumerates all units that are in the circle of Loc(x, y) withing a radius of r,
//: but only if their distance to the center is more then r-w.
//: n / p \
//: . .-*"*-. . n
//: / p * n * \
//: \ * n * / n
//: * *-.,.-* *
//: \ /
//: *.__________.*
//: n = not picked
//: p = picked
//: enumGroup PosX PosY Radius Width(Border)
function EnumUnitsInCircleBorder takes group theGroup, real x, real y, real r, real w returns nothing
local RangeFilter rf = RangeFilter.create(getUnitFilter(), x, y, r-w, true)
call setUnitFilter(rf)
call EnumUnitsInRange(theGroup, x, y, r)
call rf.destroy()
endfunction
endlibrary
//TESH.scrollpos=86
//TESH.alwaysfold=0
library CustomFilterExamples initializer all requires CustomFilter, CFLib, CFEnum
//: ------------------------------------------------------------------------
//: Lets do some basic stuff at first.
private function e1 takes nothing returns nothing
//: Create a new group
local group g = CreateGroup()
//: and lets use the alive filter
call setUnitFilter(FILTER_UNIT_ALIVE)
//: and now lets enumerate units into the group.
call GroupEnumUnitsInRange(g, 0., 0., 512., UNIT_FILTER)
//: Lets do a little check if we picked any unit
call BJDebugMsg("We picked " + I2S(CountUnitsInGroup(g)) + " units!")
endfunction
//: ------------------------------------------------------------------------
//: Lets do something more advanced. We pick all units that are non-heroes
//: and print them.
private function e2_Print takes nothing returns nothing
//: Notice how we can access to the global variable
//: FILTER_UNIT at any place!
call BJDebugMsg(GetUnitName(FILTER_UNIT))
endfunction
private function e2 takes nothing returns nothing
local group g = CreateGroup()
call setUnitFilter(FILTER_UNIT_NOT_HERO)
//: We actually need to link the enum with function
//: Do this AFTER applying the filter!
call setOnUnitEnum(e2_Print)
call GroupEnumUnitsInRange(g, 0., 0., 512., UNIT_FILTER)
endfunction
//: ------------------------------------------------------------------------
//: Lets do some advanced filtering this time.
//: Who wants all units to be filtered, everytime?
//: To face it, we want only 5 units that are not undead.
private function e3 takes nothing returns nothing
local group g = CreateGroup()
//: Notice how we can connect filters inside each other!
local LimitedFilter lf = LimitedFilter.create(FILTER_UNIT_NOT_UNDEAD, 5)
call setUnitFilter(lf)
call GroupEnumUnitsInRange(g, 0., 0., 512., UNIT_FILTER)
call lf.destroy()
//: Lets do a little check if we picked any unit
call BJDebugMsg("We picked " + I2S(CountUnitsInGroup(g)) + " units!")
endfunction
//: ------------------------------------------------------------------------
//: We still haven't concatigated conditions yet.
//: This time, we want to have an unit that is either dead or alive and
//: not an hero
private function e4 takes nothing returns nothing
local group g = CreateGroup()
//: Notice how we can connect this two filters
//: with an AND connector.
local AndFilter ad = AndFilter.create(FILTER_UNIT_ALIVE, FILTER_UNIT_HERO, false)
//: Notice how we can now connect 2 filters
//: of different types with this or filter
local OrFilter of = OrFilter.create(FILTER_UNIT_DEAD, ad, false)
call setUnitFilter(of)
call GroupEnumUnitsInRange(g, 0., 0., 512., UNIT_FILTER)
call of.destroy()
call ad.destroy()
//: Lets do a little check if we picked any unit
call BJDebugMsg("We picked " + I2S(CountUnitsInGroup(g)) + " units!")
endfunction
//: ------------------------------------------------------------------------
//: Now we want to do something more advanced.
//: This time we want to have a filter for all units of a spell.
//: The filter is for disentigrate from Diablo III, so we use the CFEnum
//: library to get new, great enumeration functions.
//: For this spell we want to have alive units only, that are enemies.
globals
private constant real DISINTEGRATE_RANGE = 128.
endglobals
private struct e5struct
private unit caster = null
private real x1 = -192
private real y1 = 0.
private real x2 = 192
private real y2 = 0.
private static method dmg takes nothing returns nothing
local real lastHp = GetUnitState(FILTER_UNIT, UNIT_STATE_LIFE)
local real newHp = lastHp - 25.
call SetUnitState(FILTER_UNIT, UNIT_STATE_LIFE, newHp)
endmethod
//: This is the method that is run every few ms.
public method e5 takes nothing returns nothing
local group g = CreateGroup()
//: Create a new allyfilter
local AllyFilter af = AllyFilter.create(Player(0), false)
//: Create a new andfilter and connect it with ally and alivefilter
local AndFilter andf = AndFilter.create(af, FILTER_UNIT_ALIVE, false)
call setUnitFilter(andf)
//: Notice how we again connect enumeration with method calls.
call setOnUnitEnum(thistype.dmg)
//: Function of the CFLib
call EnumUnitsInRangeOfLine(g, .x1, .y1, .x2, .y2, DISINTEGRATE_RANGE)
call andf.destroy()
call af.destroy()
endmethod
endstruct
//: ------------------------------------------------------------------------
//: Lets use our own condition functions.
private function e6_Print takes nothing returns nothing
//: Notice how we can access to the global variable
//: FILTER_UNIT at any place!
call BJDebugMsg(GetUnitName(FILTER_UNIT))
endfunction
private function e6_Cond takes nothing returns boolean
return GetUnitState(FILTER_UNIT, UNIT_STATE_LIFE) >= 100.
endfunction
private function e6 takes nothing returns nothing
local group g = CreateGroup()
//: Lets filter all units (TRUE_FILTER) that match our condition
local UnitCondFilter cf = UnitCondFilter.create(TRUE_FILTER, e6_Cond, false)
call setUnitFilter(cf)
//: Notice how we again connect enumeration with method calls.
call setOnUnitEnum(e6_Print)
call GroupEnumUnitsInRange(g, 0., 0., 512., UNIT_FILTER)
call cf.destroy()
//: Thats it. Was is that hard?
endfunction
//: ------------------------------------------------------------------------
//: Now you know about a lot of functionality of this system.
//: Thanks for downloading and using.
//: ------------------------------------------------------------------------
private function all takes nothing returns nothing
local e5struct e5i = e5struct.create()
//call e1()
//call e2()
//call e3()
//call e4()
call e5i.e5()
//call e6()
endfunction
endlibrary