Notice: Stable version.
Changelog:
Enjoy it, comments and suggestions are welcome.
JASS:
library LightUnitIndexer /* v0.2.1
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Light Unit Indexer by Ruke
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* Assigns unique ids to units.
*
* Why choose it?
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* If you need a light system, who does not requires other systems, work with
* hashtable instead of UnitUserData (custom value in GUI) and does not use
* interfaces, structs and other stuffs like that, choose it.
*
* Also, if you need a GUI friendly unit indexer, choose it too :3.
*
* How to import?
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* First, create a new trigger called LightUnitIndexer and then paste this code.
* You also will need to create a new ability based on Defend (Human -> Units),
* no need to modify nothing on it.
*
* Functions
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* function TriggerRegisterIndexEvent takes trigger t returns event
* function TriggerRegisterDeIndexEvent takes trigger t returns event
*
* function GetIndexedUnit takes nothing returns unit
* - Returns the unit who has been indexed
* function GetDeIndexedUnit takes nothing returns unit
* - Returns the unit who has been deindexed
*
* function GetUnitById takes integer i returns unit
* function GetUnitId takes unit u returns integer
*
* function IsIndexLocked takes integer i returns boolean
* function LockIndex takes integer i, boolean b returns nothing
* - Lock (or unlock) the index. If you lock it,
* - the index will not be recycled when the
* - unit is deindexed
*
* function IsUnitIndexed takes unit u returns boolean
*
* Thanks to
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* Jesus4Lyf
* Nestharus
* muZk
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
globals
// 1.00 = Index event
// 2.00 = DeIndex event
// ------------------------------------------
// Uncomment this line if you will not create
// the variable LUIS_EVENT with the variable
// editor (Ctrl + B)
// ------------------------------------------
//real udg_LUIS_EVENT = 0.00
// Change it to the rawcode of the ability based on
// Defend (Human -> Units)
private constant integer LEAVER_ABILITY = 'LUIS'
private integer array lock
private integer array recycle
private integer recycleCount = 0
private group indexCache = CreateGroup()
private group deIndexCache = CreateGroup()
private boolean inCache = true
private unit array units
private integer count = 0
private unit eventUnit = null
private hashtable ht = InitHashtable()
endglobals
function TriggerRegisterIndexEvent takes trigger t returns event
return TriggerRegisterVariableEvent(t, "udg_LUIS_EVENT", EQUAL, 1.00)
endfunction
function TriggerRegisterDeIndexEvent takes trigger t returns event
return TriggerRegisterVariableEvent(t, "udg_LUIS_EVENT", EQUAL, 2.00)
endfunction
function GetIndexedUnit takes nothing returns unit
return eventUnit
endfunction
function GetDeIndexedUnit takes nothing returns unit
return eventUnit
endfunction
function GetUnitById takes integer i returns unit
return units[i]
endfunction
function GetUnitId takes unit u returns integer
return LoadInteger(ht, GetHandleId(u), 0)
endfunction
function IsIndexLocked takes integer i returns boolean
return lock[i] > 0
endfunction
function LockIndex takes integer i, boolean b returns nothing
if (b) then
set lock[i] = lock[i] + 1
else
set lock[i] = lock[i] - 1
endif
endfunction
function IsUnitIndexed takes unit u returns boolean
return HaveSavedInteger(ht, GetHandleId(u), 0)
endfunction
private function FireEvent takes unit u, real r returns nothing
local unit prev = eventUnit
set eventUnit = u
set udg_LUIS_EVENT = r
set udg_LUIS_EVENT = 0.00
set eventUnit = prev
set prev = null
endfunction
private function IndexUnit takes unit u returns nothing
local integer i
if (IsUnitIndexed(u) == false) then
if (recycleCount == 0) then
set count = count + 1
set i = count
else
set i = recycle[recycleCount]
set recycleCount = recycleCount - 1
endif
call SaveInteger(ht, GetHandleId(u), 0, i)
call UnitAddAbility(u, LEAVER_ABILITY)
call UnitMakeAbilityPermanent(u, true, LEAVER_ABILITY)
if (inCache) then
call GroupAddUnit(indexCache, u)
else
call FireEvent(u, 1.00)
endif
endif
endfunction
private function RemoveIndex takes unit u returns nothing
local integer handleId = GetHandleId(u)
local integer id = GetUnitId(u)
if (IsIndexLocked(id) == false) then
set recycleCount = recycleCount + 1
set recycle[recycleCount] = id
endif
set units[id] = null
call SaveInteger(ht, handleId, 0, 0)
call RemoveSavedInteger(ht, handleId, 0)
endfunction
private function DeIndexUnit takes unit u returns nothing
if (GetUnitAbilityLevel(u, LEAVER_ABILITY) == 0 and IsUnitIndexed(u)) then
if (inCache) then
call GroupAddUnit(deIndexCache, u)
else
call FireEvent(u, 2.00)
call RemoveIndex(u)
endif
endif
endfunction
private function OnEnter takes nothing returns boolean
call IndexUnit(GetFilterUnit())
return false
endfunction
private function OnLeave takes nothing returns boolean
call DeIndexUnit(GetFilterUnit())
return false
endfunction
private function Run takes nothing returns nothing
local unit u
set inCache = false
loop
set u = FirstOfGroup(indexCache)
exitwhen u == null
call GroupRemoveUnit(indexCache, u)
call FireEvent(u, 1.00)
endloop
loop
set u = FirstOfGroup(deIndexCache)
exitwhen u == null
call GroupRemoveUnit(deIndexCache, u)
call FireEvent(u, 2.00)
call RemoveIndex(u)
endloop
call DestroyGroup(indexCache)
call DestroyGroup(deIndexCache)
call DestroyTimer(GetExpiredTimer())
set indexCache = null
set deIndexCache = null
endfunction
private module Init
private static method onInit takes nothing returns nothing
local integer maxPlayers = bj_MAX_PLAYERS
local trigger t = CreateTrigger()
local boolexpr onLeave = Condition(function OnLeave)
local region r = CreateRegion()
local player p
local unit u
loop
exitwhen maxPlayers < 0
set p = Player(maxPlayers)
call TriggerRegisterPlayerUnitEvent(t, p, EVENT_PLAYER_UNIT_ISSUED_ORDER, onLeave)
call SetPlayerAbilityAvailable(p, LEAVER_ABILITY, false)
call GroupEnumUnitsOfPlayer(bj_lastCreatedGroup, p, null)
loop
set u = FirstOfGroup(bj_lastCreatedGroup)
exitwhen u == null
call GroupRemoveUnit(bj_lastCreatedGroup, u)
call IndexUnit(u)
endloop
set maxPlayers = maxPlayers - 1
endloop
call RegionAddRect(r, GetWorldBounds())
call TriggerRegisterEnterRegion(CreateTrigger(), r, Condition(function OnEnter))
set t = null
set onLeave = null
set r = null
set p = null
call TimerStart(CreateTimer(), 0, false, function Run)
endmethod
endmodule
private struct LUI extends array
implement Init
endstruct
endlibrary
Changelog:
- v0.2.1
- Added LUI struct
- Added Init module
- v0.2.0
- Added RemoveIndex function
- Changed documentation
- Initialization feature
- Added FireEvent function
- v0.1.0
- Added index lock/unlock feature (thanks Nestharus)
- Fixed buggy UNIT_EVENT (thanks Nestharus)
- v0.0.1
- Changed name (RIP LUIS )
Enjoy it, comments and suggestions are welcome.
Attachments
Last edited: