System Units' Inventory Data

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
JASS:
/////////////////////////////////////////////////////////
//          Units' Inventory Data (UID) v2.0.0 
//              by kingking
//
//=================
//  What is this?
//=================
//  ~ UID is meant to be replacing missing native, like
//    GetItemOwner, GetItemInventoryPosition.
//  ~ UID is able to detect an item carrier changes position
//    of item(s) in it's inventory.
//
//=========================================
//  Enough propagation? Let's try it out!
//=========================================
//  Functions :
//  ~ UID_RegisterOnMoveItem(trigger) -> EventReg
//  ~ UID_UnregisterOnMoveItem(trigger)
//
//  ~ GetItemOwner(item) -> unit
//  ~ GetItemInventoryPosition(item) -> integer
//   (returns -1 if it is not carried by a unit.)
//  ~ GetMovedItem() -> item
//  ~ GetLastInventoryPosition() -> integer
//   (Position of item in inventory before changing.)
//  ~ GetUnitItemInSlot(unit,slot) -> item
//
//  Constants :
//  ~ UID_FIRST_INVENTORY_ID
// 
//================
//  Details :
//================
//  Slot Position's Mapping :
//  -------------
//  |  0  |  1  |
//  -------------
//  |  2  |  3  |
//  ------------
//  |  4  |  5  |
//  -------------
//
//==============
//  Requires :
//==============
//  Jasshelper 0.A.2.B
//  AIDS
//  Event
//  Table
//
//==============
//  Credits :
//==============
//  Executor - Finding out the slot swapping event.
//  Jesus4Lyf - Making AIDS.
//
//////////////////////////////////////////////////////////
library UID requires AIDS, T32, Event, Table
    
    globals
        public constant integer FIRST_INVENTORY_ID = 852002
        public constant integer LAST_INVENTORY_ID = 852007
    endglobals
    
    globals
        private Event OnMoveItem
        private item array MovedItem
        private integer array LastPosition
        private integer StackLevel = 0
    endglobals
    
    public function RegisterOnMoveItem takes trigger trig returns EventReg
        return OnMoveItem.register(trig)
    endfunction
    
    public function UnregisterOnMoveItem takes trigger trig returns nothing
        call OnMoveItem.unregister(trig)
    endfunction
    
    private keyword items
    private keyword UnitStruct
    
    private struct ItemStruct
        private static Table dat
        integer position
        item it
        integer hid
        unit owner
        
        private method periodic takes nothing returns nothing
            if GetWidgetLife(this.it) < 0.405 then
                set thistype.dat[this.hid] = 0
                call this.stopPeriodic()
                call this.destroy()
            endif
        endmethod
        
        static method operator [] takes item i returns thistype
            local integer id = GetHandleId(i)
            local thistype this = thistype.dat[id]
            if id == 0 then
                return 0
            elseif this == 0 then
                set this = thistype.allocate()
                set this.it = i
                set this.position = -1
                set this.hid = id
                set this.owner = null
                set thistype.dat[id] = this
                call this.startPeriodic()
            endif
            return this
        endmethod
        
        implement T32x
        
        private static method onInit takes nothing returns nothing
            set thistype.dat = Table.create()
            set thistype(0).position = -1
        endmethod
    endstruct
    
    private type items extends ItemStruct array [6]
    
    private struct UnitStruct extends array
        items items
        
        method periodic takes nothing returns nothing
            local integer i = 0
            local integer maxSize = UnitInventorySize(this.unit)
            local item it
            loop
            exitwhen i == maxSize
                set it = UnitItemInSlot(this.unit,i)
                if it != null then
                    set ItemStruct[it].position = i
                    set ItemStruct[it].owner = this.unit
                    
                    set this.items<i> = ItemStruct[it]
                endif
                set i = i + 1
            endloop
        endmethod
        
        private method AIDS_onCreate takes nothing returns nothing
            call this.startPeriodic()
            set this.items = items.create()
        endmethod
        
        private method AIDS_onDestroy takes nothing returns nothing
            local integer i = 0
            
            loop
            exitwhen i == 6
                set this.items<i>.owner = null
                set this.items<i>.position = -1
                set i = i + 1
            endloop
            
            call this.stopPeriodic()
            call this.items.destroy()
        endmethod
        
        implement T32x
        //! runtextmacro AIDS()
    endstruct
    
    function GetItemOwner takes item i returns unit
        return ItemStruct<i>.owner
    endfunction
    
    function GetItemInventoryPosition takes item i returns integer
        return ItemStruct<i>.position
    endfunction
    
    function GetMovedItem takes nothing returns item
        return MovedItem[StackLevel]
    endfunction
    
    function GetLastInventoryPosition takes nothing returns integer
        return LastPosition[StackLevel]
    endfunction
    
    function GetUnitItemInSlot takes unit u, integer slot returns item
        return UnitStruct<u>.items[slot].it
    endfunction

    private struct Initializer extends array
        private static method onPickUp takes nothing returns boolean
            local ItemStruct i = ItemStruct[GetManipulatedItem()]
            local integer pos = 0
            
            set i.owner = GetTriggerUnit()
            loop
            exitwhen pos == 6
                if UnitItemInSlot(i.owner,pos) == GetManipulatedItem() then
                    set i.position = pos
                    set pos = 5
                endif
                set pos = pos + 1
            endloop
            return false
        endmethod
        
        private static method onDrop takes nothing returns boolean
            local ItemStruct i = ItemStruct[GetManipulatedItem()]
            set UnitStruct[i.owner].items[i.position] = 0
            set i.owner = null
            set i.position = -1
            return false
        endmethod
        
        private static method onMove takes nothing returns boolean
            local integer orderId = GetIssuedOrderId()
            local unit u = GetTriggerUnit()
            local integer originalPos
            local ItemStruct movedItem
            local ItemStruct originalItem
            
            set orderId = orderId - FIRST_INVENTORY_ID
                
            set movedItem = ItemStruct[GetOrderTargetItem()]
            set originalItem = UnitStruct<u>.items[orderId]

            if movedItem != originalItem then
                if originalItem != 0 then
                    set originalItem.position = movedItem.position
                endif
                set originalPos = movedItem.position
                set movedItem.position = orderId
                
                set UnitStruct<u>.items[orderId] = movedItem
                set UnitStruct<u>.items[originalPos] = originalItem

                set StackLevel = StackLevel + 1
                set MovedItem[StackLevel] = movedItem.it
                set LastPosition[StackLevel] = originalPos
                call OnMoveItem.fire()
                set StackLevel = StackLevel - 1
            endif
            set u = null
            return false
        endmethod
        
        private static method checkOrder takes nothing returns boolean
            return GetIssuedOrderId() &gt;= FIRST_INVENTORY_ID and GetIssuedOrderId() &lt;= LAST_INVENTORY_ID
        endmethod
        
        private static method onInit takes nothing returns nothing
            local trigger pickUp = CreateTrigger()
            local trigger drop = CreateTrigger()
            local trigger move = CreateTrigger()

            set OnMoveItem = Event.create()

            call TriggerRegisterAnyUnitEventBJ(pickUp,EVENT_PLAYER_UNIT_PICKUP_ITEM)
            call TriggerRegisterAnyUnitEventBJ(drop,EVENT_PLAYER_UNIT_DROP_ITEM)
            call TriggerRegisterAnyUnitEventBJ(move,EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
            
            call TriggerAddCondition(pickUp,Condition(function thistype.onPickUp))
            call TriggerAddCondition(drop,Condition(function thistype.onDrop))
            call TriggerAddCondition(move,And(Condition(function thistype.checkOrder),Condition(function thistype.onMove)))
        endmethod
    endstruct
    
endlibrary
</u></u></u></u></i></i></i></i></i>


Add Ons :
JASS:
////////////////////////////////////////////////////////////
//  Charge Splitter v1.0.1
//      by kingking
//
//  =========================
//  What is Charge Splitter?
//  =========================
//  Charge Splitter allows auto splitting of
//  items&#039; charges when it is moved to 
//  another slot in inventory of a unit.
//
//  ================
//  How to use?
//  ================
//  ChargeSplitter(item&#039;s id, amount of charge to be splited)
//  ChargeSplitter_RegisterEvent(trigger) -&gt; EventReg
//  ChargeSplitter_UnregisterEvent(trigger)
//  GetSplittedItem() -&gt; item
//
//  ================
//  Requires :
//  ================
//  Units&#039; Inventory Data
//  Table
//  Event
//  
//  NOTE : You can&#039;t use ChargeSplitter and ChargeMerger on same id, else it will bug.
///////////////////////////////////////////////////////////////
library ChargeSplitter requires UID, Table, Event

    globals
        private Table ChargeCount
        private Table Block
        private Event OnSplitItem
        private item array ItemStack
        private integer StackLevel = 0
        private timer Timer
        private integer array BStack
        private integer BStackCount = 0
    endglobals
    
    public function RegisterEvent takes trigger whichTrigger returns EventReg
        return OnSplitItem.register(whichTrigger)
    endfunction
    
    public function UnregisterEvent takes trigger whichTrigger returns nothing
        call OnSplitItem.unregister(whichTrigger)
    endfunction
    
    function GetSplittedItem takes nothing returns item
        return ItemStack[StackLevel]
    endfunction
    
    function ChargeSplitter takes integer id, integer charge returns nothing
        set ChargeCount[id] = charge
    endfunction
    
    private function Reset takes nothing returns nothing
        loop
        exitwhen BStackCount == 0
            set Block[BStack[BStackCount]] = 0
            set BStackCount = BStackCount - 1
        endloop
    endfunction
    
    private function Cond takes nothing returns boolean
        local unit u = GetTriggerUnit()
        local item it = GetMovedItem()
        local integer itemId = GetItemTypeId(it)
        local integer charges = ChargeCount[itemId]
        local integer itCharge = GetItemCharges(it)
        local integer index
        local item it2 = null
        local timer t = null
        if GetUnitItemInSlot(u,GetLastInventoryPosition()) == null and Block[GetHandleId(it)] == 0 and charges != 0 and itCharge &gt; charges then
            call SetItemCharges(it,itCharge - charges)
            set it2 = UnitAddItemById(u,itemId)
            call SetItemCharges(it2,charges)
            set index = GetHandleId(it2)
            set BStackCount = BStackCount + 1
            set BStack[BStackCount] = index
            set Block[index] = 1
            call TimerStart(t,.0,false,function Reset)
            call IssueTargetOrderById(u,UID_FIRST_INVENTORY_ID + GetLastInventoryPosition(),it2)
            set StackLevel = StackLevel + 1
            set ItemStack[StackLevel] = it2
            call OnSplitItem.fire()
            set StackLevel = StackLevel - 1
        endif
        set u = null
        set it = null
        set it2 = null
        set t = null
        return false
    endfunction
    
    private struct Initializer extends array
        private static method onInit takes nothing returns nothing
            local trigger trig = CreateTrigger()
            call UID_RegisterOnMoveItem(trig)
            call TriggerAddCondition(trig,Condition(function Cond))
            set Timer = CreateTimer()
            set ChargeCount = Table.create()
            set Block = Table.create()
            set OnSplitItem = Event.create()
        endmethod
    endstruct
    
endlibrary


JASS:
////////////////////////////////////////////////////////////
//  Charge Merger v1.0.1
//      by kingking
//
//  =========================
//  What is Charge Splitter?
//  =========================
//  Charge Splitter allows auto merging of
//  items&#039; charges when it is moved to 
//  another slot in inventory of a unit which has same
//  type of item.
//
//  ================
//  How to use?
//  ================
//  MergeCharge(item&#039;s id)
//  ChargeMerger_RegisterEvent(trigger) -&gt; EventReg
//  ChargeMerger_UnregisterEvent(trigger)
//  GetMergedItem() -&gt; item
//
//  ================
//  Requires :
//  ================
//  Units&#039; Inventory Data
//  
//  NOTE : You can&#039;t use ChargeSplitter and ChargeMerger on same id, else it will bug.
///////////////////////////////////////////////////////////////
library ChargeMerger requires UID, Event

    globals
        private Table IsMergeable
        private Event OnMergeItem
        private item array ItemStack
        private integer StackLevel = 0
    endglobals
    
    public function RegisterEvent takes trigger whichTrigger returns EventReg
        return OnMergeItem.register(whichTrigger)
    endfunction
    
    public function UnregisterEvent takes trigger whichTrigger returns nothing
        call OnMergeItem.unregister(whichTrigger)
    endfunction
    
    function GetMergedItem takes nothing returns item
        return ItemStack[StackLevel]
    endfunction
    
    function MergeCharge takes integer id returns nothing
        set IsMergeable[id] = 1
    endfunction
    
    private function Cond takes nothing returns boolean
        local item it = GetMovedItem()
        local item it2 = GetUnitItemInSlot(GetTriggerUnit(),GetLastInventoryPosition())
        local integer itId = GetItemTypeId(it)
        local integer it2Id = GetItemTypeId(it2)
        if it != it2 and IsMergeable[itId] == 1 and itId == it2Id then
            call SetItemCharges(it,GetItemCharges(it) + GetItemCharges(it2))
            call RemoveItem(it2)
            set StackLevel = StackLevel + 1
            set ItemStack[StackLevel] = it
            call OnMergeItem.fire()
            set StackLevel = StackLevel - 1
        endif
        set it = null
        set it2 = null
        return false
    endfunction
    
    private struct Initializer extends array
        private static method onInit takes nothing returns nothing
            local trigger trig = CreateTrigger()
            call UID_RegisterOnMoveItem(trig)
            call TriggerAddCondition(trig,Condition(function Cond))
            set IsMergeable = Table.create()
            set OnMergeItem = Event.create()
        endmethod
    endstruct
    
endlibrary


AIDS | Event | Table | T32
v1.0.1 : Fixed item's position not updating when swapping position to each other item. Changed to GetManipulatedItem.
v1.0.2 : Changed slot coordination to fit Warcraft 3's standard. Added Blue and Red flavors.
v1.0.3 : Removed : UID_Register/UnregisterOnPickUpItem(trigger), UID_Registe/UnregisterrOnDropItem(trigger), UID_Register/UnregisterOnChangeItemPosition(trigger), UID_Register/UnregisterOnSellItem(trigger), UID_Register/UnregisterOnPawnItem(trigger), UID_Register/UnregisterOnUseItem(trigger), GetItemInUnitBySlot
Changes : UID_RegisterOnChangeItemPosition -> UID_RegisterOnMoveItem. Removed the usage of hashtable, now uses dynamic arrays.
v1.0.4 : Publiclized FIRST_INVENTORY_ID. Changed the position of firing event. Added GetUnitItemInSlot again, (UnitItemInSlot does not work well in OnMove event), Changed UID_GetTriggerItem to GetMovedItem for better naming convention.
v1.0.5 : Switched from IDEA to Table.
v2.0.0 : Optimized code. Added T32 as requirement. Also fix potential bugs.
 

Attachments

  • UnitsInventoryData.w3x
    52 KB · Views: 540

Romek

Super Moderator
Reaction score
963
Link to required systems? Example code? Demo map?
Don't just post the code, and nothing else in a post.
 

Executor

I see you
Reaction score
57
JASS:
.
    function GetItemInUnitBySlot takes unit whichUnit, integer slot returns item
        return LoadItemHandle(hasht,GetUnitId(whichUnit),slot)
    endfunction

native function UnitItemInSlot takes unit whichUnit, integer slot returns item

// is the hashtable really faster?!


JASS:
.
        call TriggerAddCondition(pickUp,Condition(function OnPickUpFunc))
        call TriggerAddCondition(drop,Condition(function OnDropFunc))
        call TriggerAddCondition(changeItemPos,Condition(function OnChangeFunc))
        // &quot;changeItemPos&quot; doesn&#039;t fit your naming convention
        // use &quot;changePos&quot;
        call TriggerAddCondition(pawn,Condition(function OnPawnItemFunc))
        call TriggerAddCondition(sell,Condition(function OnSellItemFunc))
        call TriggerAddCondition(use,Condition(function OnUseItemFunc))


JASS:
.
        set OnDropItem = Event.create()
        set OnChangeItemPosition = Event.create()
        // same..
        // what about &quot;OnMoveItem&quot; ?
        set OnPawnItem = Event.create()


JASS:
            set i = i - FIRST_INVENTORY_ID + 1
// &quot;+1&quot; doesn&#039;t make sense
// in Jass the inventory is indexed from 0 till 5, so why convert it?


JASS:
Widget2Item(widget) //where is this function declared?
 

Azlier

Old World Ghost
Reaction score
461
Somewhat unreliable considering that IDEA has some issues with creating items in some cases.

Should work fine in any normal scenario, hopefully.

And why are you using [lJASS]GetTriggerWidget[/lJASS] in place of, say, [lJASS]GetManipulatedItem[/lJASS] where it is possible to use the latter?
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
Link to required systems? Example code? Demo map?
Don't just post the code, and nothing else in a post.

Shall post it later.

// is the hashtable really faster?!
You can use UnitItemInSlot instead of it, they are same. ;)

// "changeItemPos" doesn't fit your naming convention
// use "changePos"

Does not matter, since users are not using it.

// what about "OnMoveItem" ?
Useful? :)

// "+1" doesn't make sense
// in Jass the inventory is indexed from 0 till 5, so why convert it?

0 is returned when the item is not carried by unit. If I follow your style, it will return 6, resulted the returned value is not standard.

//where is this function declared?
Typecasting.

GetManipulatedItem
Will use it if it is usable.

Updated to v1.0.1
 

Executor

I see you
Reaction score
57
// is the hashtable really faster?!
You can use UnitItemInSlot instead of it, they are same. ;)

No they are not. You index from 1 till 6 and UnitItemInSlot uses 0 till 5.

// "+1" doesn't make sense
// in Jass the inventory is indexed from 0 till 5, so why convert it?

0 is returned when the item is not carried by unit. If I follow your style, it will return 6, resulted the returned value is not standard.

You could return -1 if fail.

//where is this function declared?
Typecasting.

and where is 'Typecasting' listed?
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
You could return -1 if fail.
Nice idea! I will update it. ;)

and where is 'Typecasting' listed?
v1.0.1 does not requires Typecasting now. :)
 

Laiev

Hey Listen!!
Reaction score
188
little error here:
JASS:
//  ~ UID_UnregisterOnChangeItemPositiontrigger)


:p
JASS:
//  ~ UID_UnregisterOnChangeItemPosition(trigger)
 

Executor

I see you
Reaction score
57
JASS:
//=================
//  What is this?
//=================
//  ~ UID is meant to be replacing missing native, like
//    GetItemOwner, GetItemInventoryPosition, GetTriggerItem.
//  ~ UID is able to detect a unit changes the item&#039;s
//    position in it&#039;s inventory.

=&gt;

//=================
//  What is this?
//=================
//  ~ UID provides item-related missing natives like
//    GetItemOwner, GetItemInventoryPosition, GetTriggerItem.
//  ~ UID is able to detect units changing carried item&#039;s
//    position in it&#039;s inventory.


JASS:
//  Functions :
//  ~ UID_RegisterOnPickUpItem(trigger) -&gt; EventReg
//  ~ UID_RegisterOnDropItem(trigger) -&gt; EventReg
//  ~ UID_RegisterOnChangeItemPosition(trigger) -&gt; EventReg
//  ~ UID_RegisterOnSellItem(trigger) -&gt; EventReg
//  ~ UID_RegisterOnPawnItem(trigger) -&gt; EventReg
//  ~ UID_RegisterOnUseItem(trigger) -&gt; EventReg
//
//  ~ UID_UnregisterOnPickUpItem(trigger)
//  ~ UID_UnregisterOnDropItem(trigger)
//  ~ UID_UnregisterOnChangeItemPosition(trigger)
//  ~ UID_UnregisterOnSellItem(trigger)
//  ~ UID_UnregisterOnPawnItem(trigger)
//  ~ UID_UnregisterOnUseItem(trigger)

=&gt;

//  Functions :
//  ~ UID_RegisterOnPickUpItem(trigger) -&gt; EventReg
//  ~ UID_RegisterOnDropItem(trigger) -&gt; EventReg
//  ~ UID_RegisterOnMoveItem(trigger) -&gt; EventReg
//  ~ UID_RegisterOnSellItem(trigger) -&gt; EventReg
//  ~ UID_RegisterOnPawnItem(trigger) -&gt; EventReg
//  ~ UID_RegisterOnUseItem(trigger) -&gt; EventReg
//
//  ~ UID_UnregisterOnPickUpItem(trigger)
//  ~ UID_UnregisterOnDropItem(trigger)
//  ~ UID_UnregisterOnMoveItem(trigger)
//  ~ UID_UnregisterOnSellItem(trigger)
//  ~ UID_UnregisterOnPawnItem(trigger)
//  ~ UID_UnregisterOnUseItem(trigger)
 

Romek

Super Moderator
Reaction score
963
JASS:
//  Flavors : Red / Blue
//  Red : Does not use hashtable, uses 2d array.
//  Blue : Use hashtable.

Oh please.. Just pick one.
Not EVERYTHING needs to come in a red and blue flavour. :thdown:

And where there's a native available that does exactly the same thing as a function you're making, that function is pointless.
 
Reaction score
456
Are you sure that Rettrue is needed? I think Blizzard fixed the bug. Was it ever needed for event registering anyway?
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
Are you sure that Rettrue is needed? I think Blizzard fixed the bug. Was it ever needed for event registering anyway?
Does not matter. :)

Bump~~~
 

SanKakU

Member
Reaction score
21
i think i figured out in my head how charge merging would work but now your system also has charge splitting, right?

uhm...can you add some instructions for testing in the test map? because although most everything was easily figured out, i didn't manage to split charges. how do you do that? should i go back and test it again?
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
I provided charge merging in test map only. You may edit it to charge splitting if you want.
 

SanKakU

Member
Reaction score
21
so...well, man. i don't get this test map at all. you got a trigger in there called charge splitter but you're not splitting any charges. why is that? are you simply trying to get it to work and leaving the unfinished code in there? and really...i don't fully comprehend what IDEA would be used for but it looks like it should be used for a lot more than what you seem to be using it for...and you're using zinc? i don't even want to go there...

it looks like you're cramming a little bit of everything into your map without even fully implementing it all...but i guess it's just a test map so whatever...

also why do you say that you charge merge automatically when really it is manual?
i'm having a hard time programming charge merging at all...
i'm totally stumped...i can't figure out why i can't do anything after picking up a charged item. i can't even show a debug message. where in your demo map is this enabled? because for some reason i'm having trouble duplicating even this simple thing. is it found in the IDEA library?
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
also, the manual charge merging is interesting but can you give a good argument for when it would be useful?
Good for RPG maps, when you are picking up lots of same item.
 

SanKakU

Member
Reaction score
21
yeah my bad...i edited that post. anyway, there's SO much in that test map... well anyway i did just now try to add my snippet to your system and it works perfectly. all you have to do is replace the real items with the fake items that my snippet uses.
 
General chit-chat
Help Users

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top