13 years
edited 8 years
Description
This library aims to provide a simple way to attach data to units via unit indexing. It offers the minimal functions required to work. This library is the result of thinking about this proposal.
Requirements:
- Alloc 2
Actual Code
Changelog:
Feel free to comment.
This library aims to provide a simple way to attach data to units via unit indexing. It offers the minimal functions required to work. This library is the result of thinking about this proposal.
Requirements:
- Alloc 2
Actual Code
/******************************************************************
* SIMPLE UNIT INDEXER V1.3 *
* By moyack *
* 2012 *
* =================================== *
* Exclusive resource from wc3jass.com *
* =================================== *
******************************************************************/
library UnitIndexer initializer init requires Alloc
/*
PURPOSE: Index units for easy attacking data to them
FUNCTIONS:
- GetUnitIndex: Takes a unit and returns its index (integer)
- GetIndexUnit: Takes an integer and returns the unit indexed
with that integer.
The following functions are meant to be used when a unit is about
to be deindexed and removed from the game, via RemoveUnit() or when
it dies.
- AddUnitEndEventCondition: Adds a contitional boolexpr variable
- AddUnitEndEventAction: Adds an action code
- GetDeindexedIndex: Returns the index of the removed unit
- GetDeindexedUnit: Returns the unit about to remove
ADVANTAGES:
- Very easy to use
- Inline friendly
- It uses arrays instead of Hashtables
- You can set the max amount of units in your map.
DISADVANTAGE:
- Uses Unit's user data, so if in your map you use this feature in
your units, this system will put issues.
CONFIGURATION: "SIZE" Constant.
Here you can define the maximum amount of units that your game will manage.
If you REAAALLLY need that, please set the SIZE variable with the required
amount, else DO NOT MODIFY ANYTHING.
CREDITS:
- Magtheridon96 & Troll-Brain for his nice support and help me notice some
flaws in the code.
*/
globals
private constant integer SIZE = 8190 // Here you set the array size, just if you need it, ok??
private integer I = 0 // Stores the deallocated unit index...
private unit U = null // Stores the deallocated unit...
private trigger T = null // a trigger which will be fired when a unit is deallocated.
endglobals
private struct data extends array [SIZE]
unit u
implement Alloc
method destroy takes nothing returns nothing
set I = this
set U = .u
if T != null then
if TriggerEvaluate(T) then
call TriggerExecute(T)
endif
endif
call SetUnitUserData(.u, 0)
set .u = null
call .deallocate()
endmethod
static method create takes unit u returns thistype
local thistype this
if GetUnitUserData(u) < 1 then
set this = thistype.allocate()
call SetUnitUserData(u, integer(this))
else
set this = thistype(GetUnitUserData(u))
endif
set this.u = u
return this
endmethod
endstruct
// public functions
function GetUnitIndex takes unit u returns integer
return GetUnitUserData(u)
endfunction
function GetIndexUnit takes integer index returns unit
return data(index).u
endfunction
function GetDeindexedIndex takes nothing returns integer
return I
endfunction
function GetDeindexedUnit takes nothing returns unit
return U
endfunction
function AddUnitEndEventCondition takes boolexpr b returns triggercondition
if T == null then
set T = CreateTrigger()
endif
return TriggerAddCondition(T, b)
endfunction
function AddUnitEndEventAction takes code c returns triggeraction
if T == null then
set T = CreateTrigger()
endif
return TriggerAddAction(T, c)
endfunction
// end public functions
private function ClearUnit takes unit u returns nothing
call data(GetUnitIndex(u)).destroy()
endfunction
hook RemoveUnit ClearUnit
private function indexit takes nothing returns boolean
return data.create(GetTriggerUnit()) < 0 // just to make it boolean :)
endfunction
private function indexit2 takes nothing returns boolean
return data.create(GetFilterUnit()) < 0 // just to make it boolean :)
endfunction
private function dead takes nothing returns boolean
if not IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) then
call ClearUnit(GetTriggerUnit())
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
local rect r = GetWorldBounds()
call TriggerRegisterEnterRectSimple(t, r)
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SUMMON)
call TriggerAddCondition(t, Condition(function indexit))
call GroupEnumUnitsInRect(bj_lastCreatedGroup, r, Condition(function indexit2))
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(t, Condition(function dead))
set t = null
set r = null
endfunction
endlibraryChangelog:
- 1.0: Initial release.
- 1.1: Added detection of units removed via [lcode=jass]RemoveUnit()[/lcode]
- 1.2: Added detection of resurrected units.
- 1.3: Added functionality to trigger a condition or a function when a unit is about to be removed from the game, via [lcode=jass]RemoveUnit()[/lcode] or when it dies. This can be useful when you need to do something with the unit about to be removed like clearing any data attachment done to it. I don't plan to add more features, only optimization unless a good reason makes merits to an addition.
Feel free to comment.

