• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[vJASS] Item stacking

Status
Not open for further replies.
Level 10
Joined
Jun 6, 2007
Messages
392
I've been trying to make a simple item stacking system.

Here's the code:
JASS:
scope ItemStacking initializer init 
    
    globals
        private constant integer STACK_MAX_AMOUNT = 100
    endglobals

    private function onPickup takes nothing returns boolean
        local integer i = 0
        local item inSlot
        local item picked = GetManipulatedItem()
        local unit u = GetManipulatingUnit()
        local integer addedCharges
        
        loop
            exitwhen i == 6
            set inSlot = UnitItemInSlot(u, i)
            if GetItemType(inSlot) == GetItemType(picked) then
                set addedCharges = IMinBJ(STACK_MAX_AMOUNT-GetItemCharges(inSlot), GetItemCharges(picked))
                call SetItemCharges(inSlot, GetItemCharges(inSlot) + addedCharges)
                call SetItemCharges(picked, GetItemCharges(picked) - addedCharges)
                if GetItemCharges(picked) == 0 then
                    call RemoveItem(picked)
                    set u = null
                    set picked = null
                    set inSlot = null
                    return false
                endif
                
            endif
            
            set i = i + 1
        endloop
        
        set u = null
        set picked = null
        set inSlot = null
    
        return false
    endfunction

    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_PICKUP_ITEM )
        call TriggerAddCondition(t, Condition(function onPickup))
        set t = null
    endfunction

endscope

The goal is to be able to stack items up to STACK_MAX_AMOUNT, however, this system has quite strange behaviour:

When I only pick up potions, it works.

If I pick up other kinds of potions, they are stacked with original potions. For example if I have 10 life potions and I pick up 5 mana potions, I will have 15 life potions.

If I pick up any other kinds of items, they are simply deleted.

Could someone find the error I've missed?
 
I can't retrace it well, but I believe it is around these lines
JASS:
 if GetItemType(inSlot) == GetItemType(picked) then
                set addedCharges = IMinBJ(STACK_MAX_AMOUNT-GetItemCharges(inSlot), GetItemCharges(picked))
                call SetItemCharges(inSlot, GetItemCharges(inSlot) + addedCharges)
                call SetItemCharges(picked, GetItemCharges(picked) - addedCharges)
                if GetItemCharges(picked) == 0 then
                    call RemoveItem(picked)
 
Level 10
Joined
Jun 6, 2007
Messages
392
For example, if I have no items and I pick up a key (which isn't used upon acquiring), the item disappears. In this case, the if statement should clearly be false, so that branch isn't executed. This bug seems quite strange.

EDIT: I replaced the comparison with "if GetItemTypeId(inSlot) == GetItemTypeId(picked) then", and now it works for most items. Also, different kinds of potions are now stacked separately as they should. However, there are still some item which get deleted.

EDIT 2: I figured out that it only works with charged items, any non-charged item is removed when acquired. So adding a following comparison after locals fixes the problem:
JASS:
if GetItemCharges(picked) == 0 then
    return false
endif
Problem Solved.
 
Last edited:
Level 19
Joined
Mar 18, 2012
Messages
1,716
Itemtype does not return the Item Id

Instead it is:
JASS:
constant itemtype ITEM_TYPE_PERMANENT                 
constant itemtype ITEM_TYPE_CHARGED                     
constant itemtype ITEM_TYPE_POWERUP                  
constant itemtype ITEM_TYPE_ARTIFACT                  
constant itemtype ITEM_TYPE_PURCHASABLE          
constant itemtype ITEM_TYPE_CAMPAIGN                 
constant itemtype ITEM_TYPE_MISCELLANEOUS            
constant itemtype ITEM_TYPE_UNKNOWN                  
constant itemtype ITEM_TYPE_ANY

You have to use GetItemTypeId

Also there are some Itemstacking Systems in the Spell Data Base. That might be helpful too.
 
Status
Not open for further replies.
Top