- Joined
- Dec 12, 2008
- Messages
- 7,385
This snippet will track a unit's inventory.
It won't cache all the items and put them in order by slot number though.
It will however track item raw codes in slots.
Code
Demo
Feel free to commentand/or suggest any additions to the API. (No. Do not ask me to change the API.)
This won't win any benchmarks, but it will cache static data and provide you with wrappers to make your lives a bit easier and your codes a bit more readable.
It won't cache all the items and put them in order by slot number though.
It will however track item raw codes in slots.
Code
JASS:
/********************************************
*
* UnitInventory
* v2.0.0.0
* By Magtheridon96
*
* - Tracks unit inventory data.
* - Makes your life a bit easier.
* - This won't win any benchmarks.
*
* Requires:
* ---------
*
* - UnitIndexer by Nestharus
* - hiveworkshop.com/forums/jass-resources-412/system-unit-indexer-172090/
* - RegisterPlayerUnitEvent by Magtheridon96
* - hiveworkshop.com/forums/jass-resources-412/snippet-registerplayerunitevent-203338/
* - Table by Bribe
* - hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/
* - OrderEvent by Bribe
* - hiveworkshop.com/forums/jass-resources-412/snippet-order-event-190871/
*
* Optional:
* ---------
*
* - TimerUtils by Vexorian
* - wc3c.net/showthread.php?t=101322
*
* (If you use my version of TimerUtils, this will take advantage of that)
*
* API:
* ----
*
* - struct UnitInventory extends array
*
* - readonly integer size
* - The size of the inventory
* - readonly integer empty
* - The number of empty slots
* - readonly integer full
* - The number of taken slots
*
* - static method operator [] takes unit whichUnit returns thistype
* - Put a unit in between the brackets and you will get the instance
*
* - method getItem takes integer slot returns item
* - Returns the item in a given slot
*
* - method getItemId takes integer slot returns integer
* - Returns the item raw code of an item in a given slot
*
* - method hasItem takes item it returns boolean
* - Determines whether a unit has a certain item or not
*
* - method hasItemId takes integer id returns boolean
* - Determines whether a unit has a certain item type (raw code) or not
*
* - method refresh takes nothing returns nothing
* - Recalculates the size of the inventory. If you have an inventory upgrade, you would need to call this.
*
********************************************/
library UnitInventory requires UnitIndexer, RegisterPlayerUnitEvent, Table, OrderEvent, optional TimerUtils
globals
private constant boolean NO_INVENTORY_UPGRADE = true
endglobals
private module Init
private static method onInit takes nothing returns nothing
local integer i = 852002
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_PICKUP_ITEM, function thistype.pickup)
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DROP_ITEM, function thistype.drop)
loop
call RegisterOrderEvent(i, function thistype.switch)
exitwhen i == 852007
set i = i + 1
endloop
endmethod
endmodule
struct UnitInventory extends array
readonly integer size
readonly integer empty
readonly integer full
private Table types
private Table hasTypes
method getItem takes integer slot returns item
return UnitItemInSlot(GetUnitById(this), slot)
endmethod
method getItemId takes integer slot returns integer
return this.types[slot]
endmethod
method hasItem takes item it returns boolean
return UnitHasItem(GetUnitById(this), it)
endmethod
method hasItemId takes integer id returns boolean
return this.hasTypes.boolean[id]
endmethod
static if NO_INVENTORY_UPGRADE then
private static method filter takes unit u returns boolean
return UnitInventorySize(u) > 0
endmethod
endif
private static method index takes nothing returns boolean
set thistype(GetIndexedUnitId()).size = UnitInventorySize(GetIndexedUnit())
set thistype(GetIndexedUnitId()).empty = thistype(GetIndexedUnitId()).size
set thistype(GetIndexedUnitId()).full = 0
if thistype(GetIndexedUnitId()).types == 0 then
set thistype(GetIndexedUnitId()).types = Table.create()
set thistype(GetIndexedUnitId()).hasTypes = Table.create()
endif
return false
endmethod
private static method deindex takes nothing returns boolean
call thistype(GetIndexedUnitId()).types.flush()
return false
endmethod
implement UnitIndexStruct
method refresh takes nothing returns nothing
local integer oldSize = this.size
set this.size = UnitInventorySize(GetUnitById(this))
set this.empty = this.empty + this.size - oldSize
endmethod
private method updateData takes nothing returns nothing
local integer slot = 0
local integer id = 0
call this.hasTypes.flush()
loop
set id = GetItemTypeId(UnitItemInSlot(GetUnitById(this), slot))
set this.types[slot] = id
set this.hasTypes.boolean[id] = true
exitwhen slot == 5
set slot = slot + 1
endloop
endmethod
private static method pickup takes nothing returns nothing
local thistype this = GetUnitUserData(GetTriggerUnit())
set this.empty = this.empty - 1
set this.full = this.full + 1
call this.updateData()
endmethod
private static method drop takes nothing returns nothing
local thistype this = GetUnitUserData(GetTriggerUnit())
set this.empty = this.empty + 1
set this.full = this.full - 1
call this.updateData()
endmethod
static if not LIBRARY_TimerUtils then
private static key dataK
private static Table data = dataK
endif
private static method zero takes nothing returns nothing
static if LIBRARY_TimerUtilsEx then
call thistype(ReleaseTimer(GetExpiredTimer())).updateData()
elseif LIBRARY_TimerUtils then
call thistype(GetTimerData(GetExpiredTimer())).updateData()
call ReleaseTimer(GetExpiredTimer())
else
call thistype(data[GetHandleId(GetExpiredTimer())]).updateData()
call DestroyTimer(GetExpiredTimer())
endif
endmethod
private static method switch takes nothing returns nothing
static if LIBRARY_TimerUtils then
call TimerStart(NewTimerEx(GetUnitUserData(GetTriggerUnit())), 0, false, function thistype.zero)
else
local timer t = CreateTimer()
set data[GetHandleId(t)] = GetUnitUserData(GetTriggerUnit())
call TimerStart(t, 0, false, function thistype.zero)
set t = null
endif
endmethod
implement Init
endstruct
endlibrary
Demo
JASS:
struct Demo extends array
private static unit hero
private static method display takes nothing returns nothing
local string s = ""
local integer i = 0
call ClearTextMessages()
loop
if UnitInventory[hero].getItem(i) != null then
set s = s + GetObjectName(UnitInventory[hero].getItemId(i)) + "\n"
else
set s = s + "null\n"
endif
exitwhen i == 5
set i = i + 1
endloop
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, s)
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "Empty slots: " + I2S(UnitInventory[hero].empty))
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "Occupied slots: " + I2S(UnitInventory[hero].full))
endmethod
private static method onInit takes nothing returns nothing
set hero = CreateUnit(Player(0), 'Hpal', 0, 0, 270)
call CreateItem('ciri', 0, 0)
call CreateItem('ciri', 0, 0)
call CreateItem('brac', 0, 0)
call CreateItem('rwiz', 0, 0)
call CreateItem('rwiz', 0, 0)
call CreateItem('stel', 0, 0)
call CreateItem('stel', 0, 0)
call TimerStart(CreateTimer(), 3, true, function thistype.display)
endmethod
endstruct
Feel free to comment
This won't win any benchmarks, but it will cache static data and provide you with wrappers to make your lives a bit easier and your codes a bit more readable.
Attachments
Last edited: