- Joined
- May 9, 2014
- Messages
- 1,820
This is my take on a Unit Indexer:
I wonder what could go wrong with the sample script.
P.S.:
Sorry for flooding the Lab with my posts, I just like posting.
Oh, this resource is not for public use, it is only for corrections of some sort.
JASS:
library UnitIndex uses optional Hashtable
native UnitAlive takes unit u returns boolean
///! external ObjectMerger w3a Adef Dfbg anam "Leave Detection"
//========================================================================================================================//
// Unit Index //
// By MyPad, January 16, 2017 //
//========================================================================================================================//
// //
// Functions used: //
//========================================================================================================================//
// //
// IndexUnit //
// This indexes the unit in question, adding a certain ability called "defend". This will not index the unit if //
// the unit was already indexed beforehand. //
// //
// UnindexUnit //
// This does what it basically says, unindexing a unit. //
// //
// GetUnitIndex //
// This retrieves the index of a unit. Useful if you want to use its' index for a spell. //
// //
//========================================================================================================================//
private function GetIndexFilter takes unit u returns boolean
if GetUnitAbilityLevel(u, 'Aloc') != 0 then
return false
elseif IsUnitType(u, UNIT_TYPE_STRUCTURE) then
return false
endif
return true
endfunction
private module UnitInit
static HashKey UnitKey
static HashKey UnitIdKey
static HashKey recNext
readonly static hashtable HASH
private static method onInit takes nothing returns nothing
local integer i = 0
set HASH = GetUniversalHash()
set UnitKey = GenerateKey()
set UnitIdKey = GenerateKey()
set recNext = GenerateKey()
loop
call SetPlayerAbilityAvailable(Player(i), 'Bfbg', false)
exitwhen i == bj_MAX_PLAYER_SLOTS
set i = i + 1
endloop
endmethod
endmodule
private struct UnitIndex extends array
private static thistype count = 0
implement UnitInit
static method unitKeyLoad takes unit u returns integer
return LoadInteger(HASH, UnitIdKey, GetHandleId(u))
endmethod
static method registerUnit takes unit u returns nothing
local thistype this
if not GetIndexFilter(u) then
return
endif
if unitKeyLoad(u) != 0 then
return
endif
if LoadInteger(HASH, recNext, 0) == 0 then
set count = count + 1
set this = count
else
set this = LoadInteger(HASH, recNext, 0)
call SaveInteger(HASH, recNext, 0, LoadInteger(HASH, recNext, LoadInteger(HASH, recNext, 0)))
endif
call SaveUnitHandle(HASH, UnitKey, this, u)
call SaveInteger(HASH, UnitIdKey, GetHandleId(u), this)
call UnitAddAbility(u, 'Dfbg')
call UnitMakeAbilityPermanent(u, true, 'Dfbg')
endmethod
static method unregisterUnit takes unit u returns nothing
local thistype this = unitKeyLoad(u)
if this == 0 then
return
endif
call RemoveSavedHandle(HASH, UnitKey, this)
call RemoveSavedInteger(HASH, UnitIdKey, GetHandleId(u))
call SaveInteger(HASH, recNext, this, LoadInteger(HASH, recNext, 0))
call SaveInteger(HASH, recNext, 0, this)
endmethod
private static method onInit takes nothing returns nothing
local rect world = GetWorldBounds()
local group enum = CreateGroup()
local unit enum_u
call GroupEnumUnitsInRect(enum, world, null)
loop
set enum_u = FirstOfGroup(enum)
exitwhen enum_u == null
call registerUnit(enum_u)
call GroupRemoveUnit(enum, enum_u)
endloop
call RemoveRect(world)
call DestroyGroup(enum)
set world = null
set enum = null
set enum_u = null
endmethod
endstruct
function IndexUnit takes unit u returns nothing
call UnitIndex.registerUnit(u)
endfunction
function UnindexUnit takes unit u returns nothing
call UnitIndex.unregisterUnit(u)
endfunction
function GetUnitIndex takes unit u returns integer
return UnitIndex.unitKeyLoad(u)
endfunction
private struct Trigs extends array
private static unit trained
private static region mapArea
private static method remove takes nothing returns boolean
if GetIssuedOrderId() == OrderId("undefend") then
debug call BJDebugMsg("was based on Defend")
if GetUnitAbilityLevel(GetTriggerUnit(), 'Dfbg') == 0 then
debug call BJDebugMsg("about to remove unit")
call UnindexUnit(GetTriggerUnit())
endif
endif
return false
endmethod
private static method condition takes nothing returns boolean
set trained = GetTrainedUnit()
call IndexUnit(trained)
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger trig = CreateTrigger()
set mapArea = CreateRegion()
call RegionAddRect(mapArea, bj_mapInitialPlayableArea)
call TriggerRegisterEnterRegion(trig, mapArea, null)
call TriggerAddCondition(trig, Condition(function thistype.condition))
set trig = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_ISSUED_ORDER)
call TriggerAddCondition(trig, Condition(function thistype.remove))
set trig = null
endmethod
endstruct
endlibrary
I wonder what could go wrong with the sample script.
P.S.:
Sorry for flooding the Lab with my posts, I just like posting.
Oh, this resource is not for public use, it is only for corrections of some sort.
Last edited: