• 🏆 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] function to check items

Status
Not open for further replies.
Level 18
Joined
Nov 21, 2012
Messages
835
Hey guys, Im sitting few hours and cannot make simple solution..
I need a function that checks if a given unit has all items (up to 4) in inventory
something like this:

JASS:
function HasAllItems takes unit u, integer i1, integer i2, integer i3, integer i4 returns boolean

it may look like
JASS:
call HasAllItems(u, 'afac', 'spsh', 'ajen', 'bgst')
*but* also like this:
JASS:
call HasAllItems(u, 'afac', 'afac', 'ajen', 0)

any help is greatly appreciated ;]
zibi
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Looks like you're trying to make an item set system: http://www.hiveworkshop.com/forums/spells-569/itemset-v-2-5-a-269599/?prev=r=20&page=2

Anyway, this does what you ate looking for, specifically:

JASS:
function UnitHasFourItemsOfType takes unit u, integer id1, integer id2, integer id3, integer id4 returns boolean
    local integer index = 4
    local integer n = 0
    local integer array types
    local boolean array has
    local integer id
    local integer result = 0
    set types[0] = id1
    set types[1] = id2
    set types[2] = id3
    set types[3] = id4
    loop
        set index = index - 1
        if types[index] == 0 then
            set has[index] = true
            set result = result + 1
        endif
        exitwhen index == 0
    endloop

    loop
        set id = GetItemTypeId(UnitItemInSlot(u, index))
        loop
            if not has[n] and id == type[n] then
                set result = result + 1
                exitwhen result == 4
                set has[n] = true
            endif
            exitwhen n == 3
            set n = n + 1
        endloop
        exitwhen result == 4
        set n = 0

        exitwhen index == 5
        set index = index + 1
    endloop

    return result == 4
endfunction
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
You may as well create a UnitHasSixItemsOfType because you are filtering 0 item types anyway.

Also, a typo on type instead of types in if not has[n] and id == type[n] then

And this will not properly check if it has 2 items of the same type.
call UnitHasFourItemsOfType(u, 'I000', 'I000', 'I000', 'I000')
One 'I000' is enough to make this return true.

And ofcourse you can make the functions to take fewer parameters but they would be this:
JASS:
function UnitCheckItems takes unit whichUnit, integer i1, integer i2, integer i3, integer i4, integer i5, integer i6 returns boolean
    //you figure it out :D
endfunction

function UnitHasFiveItemsOfType takes unit whichUnit, integer i1, integer i2, integer i3, integer i4, integer i5 returns boolean
    return UnitCheckItems(whichUnit, i1, i2, i3, i4, i5, 0)
endfunction
function UnitHasFourItemsOfType takes unit whichUnit, integer i1, integer i2, integer i3, integer i4 returns boolean
    return UnitCheckItems(whichUnit, i1, i2, i3, i4, 0, 0)
endfunction
function UnitHasThreeItemsOfType takes unit whichUnit, integer i1, integer i2, integer i3 returns boolean
    return UnitCheckItems(whichUnit, i1, i2, i3, 0, 0, 0)
endfunction
function UnitHasTwoItemsOfType takes unit whichUnit, integer i1, integer i2 returns boolean
    return UnitCheckItems(whichUnit, i1, i2, 0, 0, 0, 0)
endfunction
//One item of type is ofcourse a separate function "UnitHasItemOfType(whichUnit, itemTypeId)"


It doesn't matter matter in which order you place the items, it doesn't matter if you place a 0 instead of an itemtype, it doesn't matter if you set the first few to 0 and the other to a higher value, it checks if the items are uniquely owned by the unit.
JASS:
function UnitCheckItems takes unit whichUnit, integer i1, integer i2, integer i3, integer i4, integer i5, integer i6 returns boolean
    local integer array heldItems
    local integer array requestedItems
    local integer index1
    local integer index2
    local integer requestedItemsLength = 6
    
    set requestedItems[0] = i1
    set requestedItems[1] = i2
    set requestedItems[2] = i3
    set requestedItems[3] = i4
    set requestedItems[4] = i5
    set requestedItems[5] = i6
    set heldItems[0] = GetItemTypeId(UnitItemInSlot(whichUnit, 0))
    set heldItems[1] = GetItemTypeId(UnitItemInSlot(whichUnit, 1))
    set heldItems[2] = GetItemTypeId(UnitItemInSlot(whichUnit, 2))
    set heldItems[3] = GetItemTypeId(UnitItemInSlot(whichUnit, 3))
    set heldItems[4] = GetItemTypeId(UnitItemInSlot(whichUnit, 4))
    set heldItems[5] = GetItemTypeId(UnitItemInSlot(whichUnit, 5))
    
    set index1 = 0
    loop
        if requestedItems[index1] == 0 then
            set requestedItemsLength = requestedItemsLength-1
            set requestedItems[index1] = requestedItems[requestedItemsLength]
            if requestedItemsLength == 0 then
                return true
            endif
        endif
        exitwhen index1 == 5
        set index1 = index1 +1
    endloop
    
    set index1 = 0
    loop
        set index2 = 0
        loop
            exitwhen index2 >= requestedItemsLength
            
            if heldItems[index1] == requestedItems[index2] then
                set requestedItemsLength = requestedItemsLength-1
                set requestedItems[index2] = requestedItems[requestedItemsLength]
                if requestedItemsLength == 0 then
                    return true
                endif
                exitwhen true
            endif
            
            set index2 = index2 +1
        endloop
        
        exitwhen index1 == 5
        set index1 = index1 +1
    endloop
    
    return false
endfunction
 
Last edited:
Level 24
Joined
Aug 1, 2013
Messages
4,657
while you are inside a loop, you can exit the loop at any given moment by running an exitwhen <boolean> statement.
If the boolean returns true, then the script exits the loop immediately.
If the boolean returns false, then nothing happens.

In some cases, you just want the loop to end no matter what happened or what the situation is.
For example, in my script, I loop through all the remaining requested items and check if they are the same as the items in your inventory.
When I have found the item, I exit that (inner) loop to continue with the next requested item.

The lowest exitwhen is for the outer loop (a simple loop from 0 to 5), the highest exitwhen is also a very standard exitwhen (for a loop from 0 to requestedItemsLength)
 
Status
Not open for further replies.
Top