/********************************Item Indexer v1.4.0 by NightSkyAurora********************************
WHAT IT DOES:
- Assigns a unique custom value (ItemUserData in JASS) to all the items in the game
- Creates an event that fires when an item is created/sold/destroyed/removed from the game
- Instantly removes items that are not removed properly when used such as Tome of Experience
IMPORTING THE SYSTEM:
1. file -> preferences -> general -> check outomaticly create unknown varibles when pasting trigger data.
2. Copy the 'Item Indexer' trigger folder and paste it in your map
3. Delete the 'variable creator' trigger
USING THE SYSTEM
If you have the item but wants to get its id, get the custom value of that item
If you have the id but wants to get the item it referes to, use IDexItems[id] to get the item
CONS:
- The item's custom value becomes unusible for other purposes
- Item Id cannot always be accessed immediately without calling IndexItem() manually
//////////////////////////// API /////////////////////////////
//////////////////////////////////////////////////////////////////
function IndexItem takes item itm returns integer
Indexes a selected item and returns it's new id
function IndexEnumItem takes nothing returns nothing
Indexes a group of items such as items in playable map area
function IndexItemOnTheGround takes real x, real y returns integer
Finds items at a nearby point and index them
returns id of last indexed item
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
IMPORTANT!!
The following functions doesn't guarentee imidiate access to an item's id
If the id is needed immediately, please use the functions as explained in the api
CreateItem
CreateItemLoc | GUI Item - Create
UnitAddItemByIdSwapped | GUI Hero - Create Item For Hero
UnitAddItemById
UnitAddItemToSlotById
UnitDropItem | Items dropped by dying units
WidgetDropItem | Items dropped by dying destructables
******************************************************************************************************/
library ItemIndexer initializer Init
globals
private integer InstCount = 0
private hashtable hash = InitHashtable()
private trigger array TrigDeindexer
private integer array recycle
endglobals
//De-index items that are destroyed
private function DeindexDestroyed takes nothing returns nothing
local trigger t = GetTriggeringTrigger()
local integer i = LoadInteger(hash, GetHandleId(t), 0)
call FlushChildHashtable(hash, GetHandleId(t))
call DisableTrigger(t)
set udg_IDex = i
set udg_ItemEvent = 2.00
set udg_ItemEvent = 0.00
call TriggerSleepAction(1)
set udg_IDex = i
set udg_ItemEvent = 4.00
set udg_ItemEvent = 0.00
call SetWidgetLife(udg_IDexItems[i], 1)
call RemoveItem( udg_IDexItems[i] )
set udg_IDexItems[i] = null
set TrigDeindexer[i] = null
set recycle[i] = recycle[0]
set recycle[0] = i
call DestroyTrigger(t)
endfunction
//De-index items that are sold
private function DeindexSold takes nothing returns nothing
local integer i = GetItemUserData(GetSoldItem())
set udg_IDex = i
set udg_ItemEvent = 3.00
set udg_ItemEvent = 0.00
set udg_IDexItems[i] = null
set recycle[i] = recycle[0]
set recycle[0] = i
//clean and destroy the item's destruction trigger
call FlushChildHashtable(hash, GetHandleId(TrigDeindexer[i]))
call DestroyTrigger(TrigDeindexer[i])
set TrigDeindexer[i] = null
endfunction
//This function ultimately assigns a unique custom value to each item and returns its id
function IndexItem takes item itm returns integer
local integer i = GetItemUserData(itm)
if not udg_IDexIsIndexed[i] and itm != null then
if recycle[0] == 0 then
set InstCount = InstCount + 1
set i = InstCount
else
set i = recycle[0]
set recycle[0] = recycle[i]
endif
set udg_IDexItems[i] = itm
call SetItemUserData(itm, i)
set udg_IDexIsIndexed[i] = true
//create a trigger that detects when the item is destroyed
set TrigDeindexer[i] = CreateTrigger()
call TriggerRegisterDeathEvent(TrigDeindexer[i], itm)
call TriggerAddAction(TrigDeindexer[i], function DeindexDestroyed)
call SaveInteger(hash, GetHandleId(TrigDeindexer[i]), 0, i)
set udg_IDex = i
set udg_ItemEvent = 1.00
set udg_ItemEvent = 0.00
endif
return i
endfunction
//Index each enum item
function IndexEnumItem takes nothing returns nothing
call IndexItem(GetEnumItem())
endfunction
//Index items near a target point
function IndexItemOnTheGround takes real x, real y returns integer
local rect r = Rect(x-256.00, y-256.00, x+256.00, y+256.00)
call EnumItemsInRect(r, null, function IndexEnumItem)
set r=null
return udg_IDex // returns last indexed item's id
endfunction
//Searches the saved locations for any items and request enum items to be indexed
private function LoadItemLoc takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer h_id = GetHandleId(t)
local real x = LoadReal(hash, h_id, 0)
local real y = LoadReal(hash, h_id, 1)
local rect r = Rect(x-256.00, y-256.00, x+256.00, y+256.00)
call EnumItemsInRect(r, null, function IndexEnumItem)
call FlushChildHashtable(hash, h_id)
call DestroyTimer(t)
set t=null
set r=null
endfunction
//Saves the location of an item and wait 0.00 seconds for the item to be created
private function SaveItemLoc takes real x, real y returns nothing
local timer t = CreateTimer()
local integer h_id = GetHandleId(t)
call SaveReal(hash, h_id, 0, x)
call SaveReal(hash, h_id, 1, y)
call TimerStart(t, 0.00, false, function LoadItemLoc)
set t=null
endfunction
//The following functions hooks all functions that can create an item to index it
private function CreateItemHook takes integer itemId, real x, real y returns nothing
call SaveItemLoc(x, y)
endfunction
private function CreateItemLocHook takes integer itemId, location loc returns nothing
call SaveItemLoc(GetLocationX(loc), GetLocationY(loc))
endfunction
private function UnitAddItemByIdSwappedHook takes integer itemId, unit u returns nothing
if UnitInventoryCount(u) == UnitInventorySize(u) then
call SaveItemLoc(GetUnitX(u), GetUnitY(u))
endif
endfunction
private function UnitAddItemByIdHook takes unit u, integer itemId returns nothing
if UnitInventoryCount(u) == UnitInventorySize(u) then
call SaveItemLoc(GetUnitX(u), GetUnitY(u))
endif
endfunction
private function UnitAddItemToSlotByIdHook takes unit u, integer i, integer slot returns nothing
call SaveItemLoc(GetUnitX(u), GetUnitY(u))
endfunction
//Index items that is dropped when a unit dies
private function UnitDropItemHook takes unit inUnit, integer inItemID returns nothing
call SaveItemLoc(GetUnitX(inUnit), GetUnitY(inUnit))
endfunction
//Index items that is dropped when a widget dies
private function WidgetDropItemHook takes widget inWidget, integer inItemID returns nothing
call SaveItemLoc(GetWidgetX(inWidget), GetWidgetY(inWidget))
endfunction
//Index items in inventories that were given to units via the map editor
private function IndexInventories takes nothing returns nothing
local integer i = 0
local unit u = GetEnumUnit()
if UnitInventorySize(u) > 0 then
loop
call IndexItem(UnitItemInSlot(u, i))
set i = i + 1
exitwhen i >= bj_MAX_INVENTORY
endloop
endif
set u=null
endfunction
//Index items that are sold to a unit
private function IndexOnCreate takes nothing returns nothing
call IndexItem(GetManipulatedItem())
endfunction
//Index items that are sold to the ground
private function IndexOnBuy takes nothing returns boolean
local real x = GetUnitX(GetOrderedUnit())
local real y = GetUnitY(GetOrderedUnit())
local item i = CreateItem(GetIssuedOrderId(), x, y)
if i != null then
call RemoveItem(i)
call SaveItemLoc(x, y)
endif
set i = null
return false
endfunction
private function Init takes nothing returns nothing
local trigger TrigIndexOnCreate = CreateTrigger()
local trigger TrigIndexOnBuy = CreateTrigger()
local trigger TrigItemDeindexer = CreateTrigger()
local rect rt = GetPlayableMapRect()
local group g = GetUnitsInRectAll(rt)
hook CreateItem CreateItemHook
hook CreateItemLoc CreateItemLocHook
hook UnitAddItemByIdSwapped UnitAddItemByIdSwappedHook
hook UnitAddItemById UnitAddItemByIdHook
hook UnitAddItemToSlotById UnitAddItemToSlotByIdHook
hook UnitDropItem UnitDropItemHook
hook WidgetDropItem WidgetDropItemHook
call TriggerRegisterAnyUnitEventBJ(TrigIndexOnCreate, EVENT_PLAYER_UNIT_PICKUP_ITEM )
call TriggerAddAction(TrigIndexOnCreate, function IndexOnCreate)
call TriggerRegisterAnyUnitEventBJ(TrigIndexOnBuy, EVENT_PLAYER_UNIT_ISSUED_ORDER )
call TriggerAddAction(TrigIndexOnBuy, function IndexOnBuy)
call TriggerRegisterAnyUnitEventBJ( TrigItemDeindexer, EVENT_PLAYER_UNIT_PAWN_ITEM )
call TriggerAddAction(TrigItemDeindexer, function DeindexSold)
call EnumItemsInRect(rt, null, function IndexEnumItem )
call ForGroup(g, function IndexInventories)
set rt = null
call DestroyGroup(g)
endfunction
endlibrary