• 🏆 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!

[JASS] Inventory System bug stopping map from being released D:

Status
Not open for further replies.
Level 13
Joined
Jul 26, 2008
Messages
1,009
Alright I'm about to release my map, Vuen's D&D Grand Project. Unfortunately the inventory system I've implemented into the map has issues. Any time I give a hero the inventory system, the hero can no longer pick up items on the ground. (Haven't tested outside of initialization)

Also the stack detection only works when they put their items in say their bag. Help would be greatly appreciated, meanwhile I'm checking through the map to detect any outside problems.

Here's the inventory system by Kricz I'm trying to use. I understand some vJASS, enough to make educated guesses for what everything does, but not enough to let me know what the problem is. :(

JASS:
library InventorySystem requires Table, ItemList, SimError BonusMod UnitMaxStateBonuses MovementBonus
    
globals
    //The Rawcodes of the Items for opening the backpack and equipment
    private constant integer EQUIPMENT_OPEN_ID  = 'I000'
    private constant integer BACKPACK_OPEN_ID   = 'I00R'
    
    //The rawcodes of the Items for closing the backpack and equipment
    private constant integer EQUIPMENT_CLOSE_ID = 'I001'
    private constant integer BACKPACK_CLOSE_ID  = 'I00S'
    
    //The rawcodes of the Items changing the pages of the backpack and equipment menu
    private constant integer EQUIPMENT_PAGE_1   = 'I003'
    private constant integer BACKPACK_PAGE_1    = 'I00T'
    
    private constant integer EQUIPMENT_PAGE_2   = 'I002'
    private constant integer BACKPACK_PAGE_2    = 'I00U'
    
    //The slots, where the items for opening backpack and equipment menu should be created
    private constant integer EQUIPMENT_SLOT     = 4
    private constant integer BACKPACK_SLOT      = 5
    
    //The place, where required items should be stored
    private constant real STORE_ITEM_X          = 0.
    private constant real STORE_ITEM_Y          = 0.
    
    //The Max Number of Charges, an item can has maximum
    constant integer MAX_ITEM_CHARGES           = 8
    
    //If true, the equipment menu will change to first page when opened
    private constant boolean CHANGE_TO_FIRST    = true
    //If trie, an item being picked up will be auto equipped, if its slot is emtpy and the hero can wear it
    private constant boolean AUTO_EQUIP         = true
    //The distance, an item can be picked up by a hero
    private constant real ITEM_PICKUP_DIST      = 225.00
    
    //Don't change this!!!
    private integer array DUMMY_ITEMS[8]
    
endglobals

private function SETUP_DUMMY_ITEMS takes nothing returns nothing
    set DUMMY_ITEMS[0] = 'I004' //Head
    set DUMMY_ITEMS[1] = 'I005' //Chest
    set DUMMY_ITEMS[2] = 'I006' //Main Hand
    set DUMMY_ITEMS[3] = 'I007' //Secondary Hand
    set DUMMY_ITEMS[4] = 'I008' //Gloves
    set DUMMY_ITEMS[5] = 'I009' //Feet
    set DUMMY_ITEMS[6] = 'I00A' //First Acessory
    set DUMMY_ITEMS[7] = 'I00B' //Second Acessory
endfunction

//EVERYTHING BELOW HERE IS SYSTEM CODE!!!
private keyword addItem

//This is the triggered item pickup and stack detection System.
private struct StackData
    private delegate Inventory inv = 0
    item item = null
    real x = 0
    real y = 0
    integer order = 0
    
    private static integer count = 0
    private static thistype array datas
    private static trigger walkTo
    
    //creates a new instance of the stackdata
    static method create takes unit hero, item which returns StackData
        local StackData this = StackData.allocate()
        set .inv = Inventory.table[hero]
        set .item = which
        set .x = GetItemX(.item)
        set .y = GetItemY(.item)
        call IssuePointOrder(.Owner, "move", .x, .y)
        set .order = GetUnitCurrentOrder(.Owner)
        set .datas[.count] = this
        set .count = .count + 1
        return this
    endmethod
    
    //checks if the issued target was an item and the order is correct
    static method check takes nothing returns boolean
        if GetOrderTargetItem() != null and (GetIssuedOrderId() == 851971) then
            call StackData.create(GetTriggerUnit(), GetOrderTargetItem())
            return true
        endif
        return false
    endmethod
    
    //just sorts and checks each stackdata...
    static method periodic takes nothing returns nothing
        local integer i = .count - 1
        loop
            exitwhen i < 0        
            if not .datas[i].control() then
                set .count = .count - 1
                if .count < 0 then
                    set .count = 0
                else
                    set .datas[i] = .datas[.count]
                endif
            endif
            set i = i - 1
        endloop
    endmethod
    
    //checks the hero and the item every interval
    method control takes nothing returns boolean
        local real dx = GetUnitX(.Owner) - .x
        local real dy = GetUnitY(.Owner) - .y
        local Item it = Item.getItemById(GetItemTypeId(.item))
        if GetUnitCurrentOrder(.Owner) != .order or GetItemX(.item) != .x or GetItemY(.item) != .y or GetWidgetLife(.Owner) <= 0.405 then
            return false
        elseif SquareRoot(dx * dx + dy * dy) <= ITEM_PICKUP_DIST and GetItemX(.item) == .x or GetItemY(.item) == .y and GetWidgetLife(.Owner) > 0.405 then
            call IssueImmediateOrder(.Owner, "stop")
            if (AUTO_EQUIP and it.Equipment and .isSlotEmpty(it.Slot) and .checkHero(it, false) and .allowauto) then
                return Inventory.equipItem(.Owner, .item, it)
            endif                
            if not .checkItemForStack(.item) then
                if not .getSlotForItem(.item) then
                    call SimError(GetOwningPlayer(.Owner), "Inventory and Backpack are full.")
                    return false
                endif
            endif
            return false
        elseif SquareRoot(dx * dx + dy * dy) > ITEM_PICKUP_DIST then
            return true
        endif
        return false
    endmethod
    
    //self explanatory..
    static method onInit takes nothing returns nothing
        set .walkTo = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(.walkTo, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
        call TriggerAddCondition(.walkTo, Condition(function thistype.check))
        call TimerStart(NewTimer(), 0.05, true, function thistype.periodic)
    endmethod
    
endstruct

//private struct required to "recreate" items in their slots when their are dragged or dropped incrorrect
private struct addItem
    delegate Inventory inv
    integer id
    integer charges
    integer slot   
    private timer t
    
    //creates a new instance for an item to a move it to a slot
    static method create takes item it, integer slot, Inventory inv returns thistype
        local thistype this = thistype.allocate()
        set .inv = inv
        set .id = GetItemTypeId(it)
        set .charges = GetItemCharges(it)
        set .slot = slot
        set .dropped = false
        call RemoveItem(it)
        set .dropped = true
        set .t = NewTimer()
        call SetTimerData(.t, this)
        call TimerStart(.t, 0.0, false, function thistype.expire)
        return this
    endmethod
    
    //0.0 second tiemr interval is required...
    private static method expire takes nothing returns nothing
        local thistype this = GetTimerData(GetExpiredTimer())
        call UnitAddItemToSlotById(.Owner, .id, .slot)
        call SetItemCharges(UnitItemInSlot(.Owner, .slot), .charges)
        call ReleaseTimer(.t)
        call .destroy()
    endmethod

endstruct

//Thanks to D1000 for creating this function
private function SearchString takes string WhichString, string ForWhat returns boolean
    local integer BaseLength = StringLength(WhichString)
    local integer SearchLength = StringLength(ForWhat)
    local integer i = 0
    
    loop
        exitwhen ForWhat == SubString(WhichString, i, i + SearchLength)
        set i = i + 1
        
        if i + SearchLength > BaseLength then
            return false
        endif
    endloop
    return true
endfunction

//The Inventory struct..
struct Inventory
    unit Owner
    string HeroClass = ""
    string ItemClasses = ""
    item array equip[8]
    integer array items[6]
    integer array backp[8]
    
    integer array charges[6]
    integer array bcharges[8]
    boolean allowauto = true
    integer bfree = 8
    boolean dropped = true
    
    private boolean open = false
    private boolean bopen = false
    private integer page = 1
    private integer bpage = 1
    public static HandleTable table
    
    
    //creates a new Inventory for the unit
    static method create takes unit whichUnit, string heroClass, string availableItemClasses returns thistype
        local thistype this = 0
        local integer i = 0
        if not .table.exists(whichUnit) then
            set this = thistype.allocate()
            set .Owner = whichUnit
            set .HeroClass = heroClass
            set .ItemClasses = availableItemClasses
            loop
                exitwhen i > 8
                set .equip[i] = CreateItem(DUMMY_ITEMS[i], STORE_ITEM_X, STORE_ITEM_Y)
                call SetItemVisible(.equip[i], false)
                set i = i + 1
            endloop
        
            call TriggerRegisterUnitEvent(.Use, .Owner, EVENT_UNIT_USE_ITEM)
            call TriggerRegisterUnitEvent(.Pickup, .Owner, EVENT_UNIT_PICKUP_ITEM)
            call TriggerRegisterUnitEvent(.Drag, .Owner, EVENT_UNIT_ISSUED_TARGET_ORDER)
            call TriggerRegisterUnitEvent(.Drop, .Owner, EVENT_UNIT_DROP_ITEM)
            
            call UnitAddItemToSlotById(.Owner, EQUIPMENT_OPEN_ID, EQUIPMENT_SLOT)
            call UnitAddItemToSlotById(.Owner, BACKPACK_OPEN_ID, BACKPACK_SLOT)
            call SetItemCharges(UnitItemInSlot(.Owner, BACKPACK_SLOT), .bfree)
            set .table[.Owner] = this
            return this
        endif
        return 0
    endmethod
    
    //opens the backpack for the unit
    public static method openBackpack takes unit whichUnit returns boolean
        local integer i = 0
        local integer i2 = 0
        local thistype this = .table[whichUnit]
        local item temp = null
        local integer add = 0
        if not .table.exists(whichUnit) then
            return false
        elseif not .bopen and not .open then
            set .bopen = true
            set .allowauto = false
             loop
                exitwhen i > 5
                set temp = UnitItemInSlot(.Owner, i)
                set .charges[i] = GetItemCharges(temp)
                set .items[i] = GetItemTypeId(temp)
                call RemoveItem(temp)
                set i = i + 1
            endloop
            call UnitAddItemToSlotById(.Owner, BACKPACK_CLOSE_ID, 5)
            if .bpage <= 1 then
                set i = 0
                loop
                    exitwhen i > 3
                    if .backp[i] != 0 then
                        call UnitAddItemToSlotById(.Owner, .backp[i], i)
                        call SetItemCharges(UnitItemInSlot(.Owner, i), .bcharges[i])
                    endif
                    set i = i + 1
                endloop
                call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_2, 4)
            elseif .bpage >= 2 then
                set i = 0
                loop
                    exitwhen i > 3
                    if .backp[i+4] != 0 then
                        call UnitAddItemToSlotById(.Owner, .backp[i+4], i)
                        call SetItemCharges(UnitItemInSlot(.Owner, i), .bcharges[i+4])
                    endif
                    set i = i + 1
                endloop
                call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_1, 4)
            endif 
            set temp = null  
            set .allowauto = true
            return true
        endif
        return true
    endmethod
    
    //opens the equipment menu
    public static method openEquipment takes unit whichUnit returns boolean
        local integer i = 0
        local thistype this = .table[whichUnit]
        local item temp = null
        if not .table.exists(whichUnit) then
            return false
        elseif not .open and not .bopen then
            set .open = true
            set .allowauto = false
            if .page <= 1 or CHANGE_TO_FIRST then
                loop
                    exitwhen i > 5
                    set temp = UnitItemInSlot(.Owner, i)
                    set .charges[i] = GetItemCharges(temp)
                    set .items[i] = GetItemTypeId(temp)
                    call RemoveItem(temp)
                    if i < 4 then
                        call SetItemVisible(.equip[i], true)
                        call UnitAddItem(.Owner, .equip[i])
                    endif
                    set i = i + 1
                endloop
                call UnitAddItemToSlotById(.Owner, EQUIPMENT_PAGE_2, 4)
            elseif .page >= 2 and not CHANGE_TO_FIRST then
                loop
                    exitwhen i > 5
                    set temp = UnitItemInSlot(.Owner, i)
                    set .charges[i] = GetItemCharges(temp)
                    set .items[i] = GetItemTypeId(temp)
                    call RemoveItem(temp)
                    if i < 4 then
                        call SetItemVisible(.equip[i+4], true)
                        call UnitAddItem(.Owner, .equip[i+4])
                    endif
                    set i = i + 1
                endloop
                call UnitAddItemToSlotById(.Owner, EQUIPMENT_PAGE_1, 4)
            endif            
            call UnitAddItemToSlotById(.Owner, EQUIPMENT_CLOSE_ID, 5)
            set .allowauto = true
            return true
        endif
        return true
    endmethod
    
    //closes the hero's backpack
    public static method closeBackpack takes unit whichUnit returns boolean
        local integer i = 0
        local item t = null
        local thistype this = .table[whichUnit]
        local item temp = null
        if not .table.exists(whichUnit) then
            return false
        elseif .bopen then
            set .bopen = false
            set .allowauto = false
            call RemoveItem(UnitItemInSlot(.Owner, 5))
            call RemoveItem(UnitItemInSlot(.Owner, 4))
            if .bpage <= 1 then
                loop
                    exitwhen i > 3
                    set temp = UnitRemoveItemFromSlot(.Owner, i)
                    set .backp[i] = GetItemTypeId(temp)
                    set .bcharges[i] = GetItemCharges(temp)
                    call RemoveItem(temp)
                    set i = i + 1
                endloop
            elseif .bpage >= 2 then
                loop
                    exitwhen i > 3
                    set temp = UnitRemoveItemFromSlot(.Owner, i)
                    set .backp[i+4] = GetItemTypeId(temp)
                    set .bcharges[i+4] = GetItemCharges(temp)
                    call RemoveItem(temp)
                    set i = i + 1
                endloop
            endif
            
            set i = 0
            loop
                exitwhen i > 5
                if .items[i] != 0 then
                    call UnitAddItemToSlotById(.Owner, .items[i], i)
                    call SetItemCharges(UnitItemInSlot(.Owner, i), .charges[i])
                endif
                set i = i + 1
            endloop
            set .bfree = .getBackpackPlace()
            call SetItemCharges(UnitItemInSlot(.Owner, BACKPACK_SLOT), .bfree)
            set .allowauto = true
            set temp = null
            return true
        endif
        return false
    endmethod
    
    //closes the hero's equipment menu
    public static method closeEquipment takes unit whichUnit returns boolean
        local integer i = 0
        local item t = null
        local thistype this = .table[whichUnit]
        local integer add = 0
        if not .table.exists(whichUnit) then
            return false
        elseif .open then
            set .open = false
            set .allowauto = false
            if .page >= 2 then
                set add = 4
            endif
            loop
                exitwhen i > 3
                set .equip[i+add] = UnitRemoveItemFromSlot(.Owner, i)
                call SetItemPosition(.equip[i+add], STORE_ITEM_X, STORE_ITEM_Y)
                call SetItemVisible(.equip[i+add], false)
                set i = i + 1
            endloop
            call RemoveItem(UnitItemInSlot(.Owner, 5))
            call RemoveItem(UnitItemInSlot(.Owner, 4))
            
            set i = 0
            loop
                exitwhen i > 5
                if .items[i] != 0 then
                    call UnitAddItemToSlotById(.Owner, .items[i], i)
                    call SetItemCharges(UnitItemInSlot(.Owner, i), .charges[i])
                endif
                set i = i + 1
            endloop
                
            call SetItemCharges(UnitItemInSlot(.Owner, BACKPACK_SLOT), .bfree)
            if CHANGE_TO_FIRST then
                set .page = 1
            endif
            set .allowauto = true
            return true
        endif
        return false
    endmethod
    
    //changes the backpack pages of the unit
    public static method changePageBackpack takes unit whichUnit returns boolean
        local integer i = 0
        local thistype this = .table[whichUnit]
        local item temp = null
        if .bopen and this != 0 then
            set .dropped = false
            call RemoveItem(UnitItemInSlot(.Owner, 4))
            set .dropped = true
            set .allowauto = false
            if .bpage <= 1 then
                loop
                    exitwhen i > 3
                    set temp = UnitRemoveItemFromSlot(.Owner, i)
                    set .backp[i] = GetItemTypeId(temp)
                    set .bcharges[i] = GetItemCharges(temp)
                    call UnitAddItemToSlotById(.Owner, .backp[i+4], i)
                    call SetItemCharges(UnitItemInSlot(.Owner, i), .bcharges[i+4])
                    call RemoveItem(temp)
                    set i = i + 1
                endloop
                call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_1, 4)
                set .bpage = 2
            elseif .bpage >= 2 then
                loop
                    exitwhen i > 3
                    set temp = UnitRemoveItemFromSlot(.Owner, i)
                    set .backp[i+4] = GetItemTypeId(temp)
                    set .bcharges[i+4] = GetItemCharges(temp)
                    call UnitAddItemToSlotById(.Owner, .backp[i], i)
                    call SetItemCharges(UnitItemInSlot(.Owner, i), .bcharges[i])
                    call RemoveItem(temp)
                    set i = i + 1
                endloop
                call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_2, 4)
                set .bpage = 1
            endif
            set .allowauto = true
            set temp = null
            return true
        endif
        return false
    endmethod
    
    //changes the equipment menu pages for the unit 
    public static method changePageEquipment takes unit whichUnit returns boolean
        local integer i = 0
        local thistype this = .table[whichUnit]
        local integer add = 0
        if .open and this != 0 then
            if .page >= 2 then
                set add = 4
            endif
            set .allowauto = false
            loop
                exitwhen i > 3
                set .equip[i+add] = UnitRemoveItemFromSlot(.Owner, i)
                call SetItemPosition(.equip[i+add], STORE_ITEM_X, STORE_ITEM_Y)
                call SetItemVisible(.equip[i+add], false)
                call UnitAddItem(.Owner, .equip[i+4-add])
                set i = i + 1
            endloop
            set .dropped = false
            call RemoveItem(UnitItemInSlot(.Owner, 4))
            set .dropped = true
            if .page >= 2 then
                call UnitAddItemToSlotById(.Owner, EQUIPMENT_PAGE_2, 4)
                set .page = 1
            elseif .page <= 1 then
                call UnitAddItemToSlotById(.Owner, EQUIPMENT_PAGE_1, 4)
                set .page = 2
            endif
            set .allowauto = true
            return true
        endif
        return false
    endmethod
    
    //Only call this method, if you can be shure, that the Item's slot is empty or it will bug!
    public static method quickEquip takes unit u, Item it returns boolean
        local thistype this = .table[u]
        if .checkHero(it, true) then
            set .equip[it.Slot] = CreateItem(it.ItemId, STORE_ITEM_X, STORE_ITEM_Y)
            call SetItemVisible(.equip[it.Slot], false)
            call SetItemDroppable(.equip[it.Slot], false)
            call .applyItemStats(it)
            return true
        endif
        return false
    endmethod    
    
    //equips an item for a hero
    public static method equipItem takes unit u, item t, Item it returns boolean
        local thistype this = .table[u]
        local integer itd1 = 0
        local integer itd2 = 0
        local integer slot = 0
        local integer i = 0
        if .checkHero(it, true) then
            if not .isItemEquipped(t) and .isSlotEmpty(it.Slot) then
                if not .open then
                    call RemoveItem(.equip[it.Slot])
                    set .equip[it.Slot] = t
                    call SetItemPosition(.equip[it.Slot], STORE_ITEM_X, STORE_ITEM_Y)
                    call SetItemVisible(.equip[it.Slot], false)
                    call SetItemDroppable(.equip[it.Slot], false)
                    call .applyItemStats(it)
                    return true
                elseif .open then
                    set .dropped = false
                    if .page <= 1 then
                        if it.Slot <= 3 then
                            if not (GetItemTypeId(UnitItemInSlot(.Owner, it.Slot)) == DUMMY_ITEMS[it.Slot]) then
                                if not .getSlotForItem(UnitItemInSlot(.Owner, it.Slot)) then
                                    call SimError(GetOwningPlayer(.Owner), "Inventory and Backpack are full.")
                                    return false
                                endif
                            else
                                call RemoveItem(UnitItemInSlot(.Owner, it.Slot))
                            endif
                            call UnitAddItemToSlotById(.Owner, it.ItemId, it.Slot)
                            call .applyItemStats(it)
                            return true
                        elseif it.Slot > 3 then
                            if not (GetItemTypeId(.equip[it.Slot]) == DUMMY_ITEMS[it.Slot]) then
                                if not .getSlotForItem(.equip[it.Slot]) then
                                    call SimError(GetOwningPlayer(.Owner), "Inventory and Backpack are full.")
                                    return false
                                endif
                            else
                                call RemoveItem(.equip[it.Slot])
                            endif
                            set .equip[it.Slot] = t
                            call SetItemPosition(.equip[it.Slot], STORE_ITEM_X, STORE_ITEM_Y)
                            call SetItemVisible(.equip[it.Slot], false)
                            call SetItemDroppable(.equip[it.Slot], false)
                            call .applyItemStats(it)
                            return true
                        endif
                    elseif .page >= 2 then
                        if it.Slot > 3 then
                            if not (GetItemTypeId(UnitItemInSlot(.Owner, it.Slot - 4)) == DUMMY_ITEMS[it.Slot]) then
                                if not .getSlotForItem(UnitItemInSlot(.Owner, it.Slot - 4)) then
                                    call SimError(GetOwningPlayer(.Owner), "Inventory and Backpack are full.")
                                    return false
                                endif
                            else
                                call RemoveItem(UnitItemInSlot(.Owner, it.Slot - 4))
                            endif
                            call UnitAddItemToSlotById(.Owner, it.ItemId, it.Slot - 4)
                            call .applyItemStats(it)
                            return true
                        elseif it.Slot <= 3 then
                            if not (GetItemTypeId(.equip[it.Slot]) == DUMMY_ITEMS[it.Slot]) then
                                if not .getSlotForItem(UnitItemInSlot(.Owner, it.Slot)) then
                                    call SimError(GetOwningPlayer(.Owner), "Inventory and Backpack are full.")
                                    return false
                                endif
                            else
                                call RemoveItem(.equip[it.Slot])
                            endif
                            set .equip[it.Slot] = t
                            call SetItemPosition(.equip[it.Slot], STORE_ITEM_X, STORE_ITEM_Y)
                            call SetItemVisible(.equip[it.Slot], false)
                            call SetItemDroppable(.equip[it.Slot], false)
                            call .applyItemStats(it)
                            return true
                        endif
                    endif
                endif
            elseif not .isSlotEmpty(it.Slot) then
                set itd1 = GetItemTypeId(t)
                set slot = .getItemSlot(t)
                call RemoveItem(t)
                set itd2 = GetItemTypeId(.equip[it.Slot])
                call RemoveItem(.equip[it.Slot])
                call .removeItemStats(Item.getItemById(itd2))
                call .applyItemStats(it)
                set .equip[it.Slot] = CreateItem(itd1, STORE_ITEM_X, STORE_ITEM_Y)
                call SetItemVisible(.equip[it.Slot], false)
                call UnitAddItemToSlotById(.Owner, itd2, slot)
                call SetItemDroppable(.equip[it.Slot], false)
                return true
            endif
        endif
        return false
    endmethod
    
    //un-equips an item for the hero
    public static method unequipItem takes unit u, item t, Item it returns boolean
        local thistype this = .table[u]
        if not .getSlotForItem(t) then
            call SimError(GetOwningPlayer(.Owner), "Inventory and Backpack are full.")
            return false
        else
            call .removeItemStats(it)
            set .equip[it.Slot] = UnitAddItemById(.Owner, DUMMY_ITEMS[it.Slot])
            return true
        endif       
    endmethod
    
    //Returns true, if the given item is equipped (or an item with the same ItemTypeId)
    public method isItemEquipped takes item whichItem returns boolean //INLINE FRIENDLY
        return GetItemTypeId(.equip[Item.getItemById(GetItemTypeId(whichItem)).Slot]) == GetItemTypeId(whichItem)
    endmethod
    
    //Returns true, if the given slot is empty
    public method isSlotEmpty takes integer Slot returns boolean //INLINE FRIENDLY
        return GetItemTypeId(.equip[Slot]) == DUMMY_ITEMS[Slot]
    endmethod
    
    //checks, if the hero has the possibility to stack the given item with another
    public method checkItemForStack takes item for returns boolean
        local integer i = 0
        local integer id = GetItemTypeId(for)
        local integer bonus = 0
        local Item it = Item.getItemById(GetItemTypeId(for))
        if not .open and not .bopen and not it.Equipment then
            loop
                exitwhen i > 5
                if GetItemTypeId(UnitItemInSlot(.Owner, i)) == id and GetItemCharges(UnitItemInSlot(.Owner, i)) + GetItemCharges(for) <= MAX_ITEM_CHARGES and GetItemCharges(UnitItemInSlot(.Owner, i)) + GetItemCharges(for) <= it.MaxStacks then
                    set bonus = GetItemCharges(for)
                    call RemoveItem(for)
                    call SetItemCharges(UnitItemInSlot(.Owner, i), GetItemCharges(UnitItemInSlot(.Owner, i)) + bonus)
                    return true
                endif
                set i = i + 1
            endloop
            
            set i = 0
            loop
                exitwhen i > 7
                if .backp[i] == id and .bcharges[i] + GetItemCharges(for) <= MAX_ITEM_CHARGES and .bcharges[i] + GetItemCharges(for) <= it.MaxStacks then
                    set bonus = GetItemCharges(for)
                    set .bcharges[i] = .bcharges[i] + bonus
                    call RemoveItem(for)
                    return true
                endif
                set i = i + 1
            endloop
        
        elseif .open then
            loop
                exitwhen i > 5
                if .items[i] == id and .charges[i] + GetItemCharges(for) <= MAX_ITEM_CHARGES and .charges[i] + GetItemCharges(for) <= it.MaxStacks then
                    set bonus = GetItemCharges(for)
                    call RemoveItem(for)
                    set .charges[i] = .charges[i] + bonus
                    return true
                endif
                set i = i + 1
            endloop
            
            set i = 0
            loop
                exitwhen i > 7
                if .backp[i] == id and .bcharges[i] + GetItemCharges(for) <= MAX_ITEM_CHARGES and .bcharges[i] + GetItemCharges(for) <= it.MaxStacks then
                    set bonus = GetItemCharges(for)
                    call RemoveItem(for)
                    set .bcharges[i] = .bcharges[i] + bonus
                    return true
                endif
                set i = i + 1
            endloop
        
        elseif .bopen then
            loop
                exitwhen i > 5
                if .items[i] == id and .charges[i] + GetItemCharges(for) <= MAX_ITEM_CHARGES and .charges[i] + GetItemCharges(for) <= it.MaxStacks then
                    set bonus = GetItemCharges(for)
                    call RemoveItem(for)
                    set .charges[i] = .charges[i] + bonus
                    return true
                endif
                set i = i + 1
            endloop
            
            if .bpage <= 1 then
                set i = 0
                loop
                    exitwhen i > 3
                    if GetItemTypeId(UnitItemInSlot(.Owner, i)) == id and GetItemCharges(UnitItemInSlot(.Owner, i)) + GetItemCharges(for) <= MAX_ITEM_CHARGES and GetItemCharges(UnitItemInSlot(.Owner, i)) + GetItemCharges(for) <= it.MaxStacks then
                        set bonus = GetItemCharges(for)
                        call RemoveItem(for)
                        call SetItemCharges(UnitItemInSlot(.Owner, i), GetItemCharges(UnitItemInSlot(.Owner, i)) + bonus)
                        return true
                    endif
                    set i = i + 1
                endloop 
                
                set i = 4
                loop
                    exitwhen i > 7
                    if .backp[i] == id and .bcharges[i] + GetItemCharges(for) <= MAX_ITEM_CHARGES and .bcharges[i] + GetItemCharges(for) <= it.MaxStacks then
                        set bonus = GetItemCharges(for)
                        call RemoveItem(for)
                        set .bcharges[i] = .bcharges[i] + bonus
                        return true
                    endif
                    set i = i + 1
                endloop
                
            elseif .bpage >= 2 then
            
                set i = 0
                loop
                    exitwhen i > 3
                    if GetItemTypeId(UnitItemInSlot(.Owner, i)) == id and GetItemCharges(UnitItemInSlot(.Owner, i)) + GetItemCharges(for) <= MAX_ITEM_CHARGES and GetItemCharges(UnitItemInSlot(.Owner, i)) + GetItemCharges(for) <= it.MaxStacks then
                        set bonus = GetItemCharges(for)
                        call RemoveItem(for)
                        call SetItemCharges(UnitItemInSlot(.Owner, i), GetItemCharges(UnitItemInSlot(.Owner, i)) + bonus)
                        return true
                    endif
                    set i = i + 1
                endloop
                
                set i = 0
                loop
                    exitwhen i > 3
                    if .backp[i] == id and .bcharges[i] + GetItemCharges(for) <= MAX_ITEM_CHARGES and .bcharges[i] + GetItemCharges(for) <= it.MaxStacks then
                        set bonus = GetItemCharges(for)
                        set .bcharges[i] = .bcharges[i] + bonus
                        call RemoveItem(for)
                        return true
                    endif
                    set i = i + 1
                endloop
            endif
            
        endif
        return false
    endmethod
    
    //checks if the hero has a empty item slot
    public method getSlotForItem takes item for returns boolean
        local integer i = 0
        local integer id = GetItemTypeId(for)
        if not .open and not .bopen then
            loop
                exitwhen i > 5
                if UnitItemInSlot(.Owner, i) == null then
                    call UnitAddItemToSlotById(.Owner, id, i)
                    call SetItemCharges(UnitItemInSlot(.Owner, i), GetItemCharges(for))
                    call RemoveItem(for)
                    return true
                endif
                set i = i + 1
            endloop
            set i = 0
            loop
                exitwhen i > 7
                if .backp[i] == 0 then
                    set .backp[i] = id
                    set .bcharges[i] = GetItemCharges(for)
                    call RemoveItem(for)
                    set .bfree = .bfree - 1
                    if not .open or .bopen then
                        call SetItemCharges(UnitItemInSlot(.Owner, BACKPACK_SLOT), .bfree)
                    endif
                    return true
                endif
                set i = i + 1
            endloop
            
        elseif .open then
            loop
                exitwhen i > 5
                if .items[i] == 0 then
                    set .items[i] = id
                    set .charges[i] = GetItemCharges(for)
                    call RemoveItem(for)
                    return true                    
                endif
                set i = i + 1
            endloop
            set i = 0
            
            loop
                exitwhen i > 7
                if .backp[i] == 0 then
                    set .backp[i] = id
                    set .bcharges[i] = GetItemCharges(for)
                    call RemoveItem(for)
                    set .bfree = .bfree - 1
                    if not .open or .bopen then
                        call SetItemCharges(UnitItemInSlot(.Owner, BACKPACK_SLOT), .bfree)
                    endif   
                    return true
                endif
                set i = i + 1
            endloop
            
        elseif .bopen then
        
            if .bpage <= 1 then
                set i = 0
                loop
                    exitwhen i > 3
                    if UnitItemInSlot(.Owner, i) == null then
                        call UnitAddItemToSlotById(.Owner, id, i)
                        call SetItemCharges(UnitItemInSlot(.Owner, i), GetItemCharges(for))
                        call RemoveItem(for)
                        return true
                    endif
                    set i = i + 1
                endloop 
                
                set i = 4
                loop
                    exitwhen i > 7
                    if .backp[i] == 0 then
                        set .backp[i] = id
                        set .bcharges[i] = GetItemCharges(for)
                        call RemoveItem(for)
                        return true
                    endif
                    set i = i + 1
                endloop
                
                set i = 0
                loop
                    exitwhen i > 5
                    if .items[i] == 0 then
                        set .items[i] = id
                        set .charges[i] = GetItemCharges(for)
                        call RemoveItem(for)
                        return true
                    endif
                    set i = i + 1
                endloop
                
            elseif .bpage >= 2 then
            
                set i = 0
                loop
                    exitwhen i > 3
                    if UnitItemInSlot(.Owner, i) == null then
                        call UnitAddItemToSlotById(.Owner, id, i)
                        call SetItemCharges(UnitItemInSlot(.Owner, i), GetItemCharges(for))
                        call RemoveItem(for)
                        return true
                    endif
                    set i = i + 1
                endloop
                
                set i = 0
                loop
                    exitwhen i > 3
                    if .backp[i] == 0 then
                        set .backp[i] = id
                        set .bcharges[i] = GetItemCharges(for)
                        call RemoveItem(for)
                        return true
                    endif
                    set i = i + 1
                endloop
                
                set i = 0
                loop
                    exitwhen i > 5
                    if .items[i] == 0 then
                        set .items[i] = id
                        set .charges[i] = GetItemCharges(for)
                        call RemoveItem(for)
                        return true
                    endif
                    set i = i + 1
                endloop
            endif
            
        endif
        return false
    endmethod
    
    private effect array fx[8] //attached effects of the items
    
    //Applies the item's stats to the hero
    private method applyItemStats takes Item it returns nothing
        call AddUnitBonus(.Owner, BONUS_ARMOR, it.Armor)
        call AddUnitBonus(.Owner, BONUS_DAMAGE, it.Dmg)
        call AddUnitBonus(.Owner, BONUS_ATTACK_SPEED, it.As)
        call AddUnitBonus(.Owner, BONUS_LIFE_REGEN, it.HpReg)
        call AddUnitBonus(.Owner, BONUS_MANA_REGEN_PERCENT, it.MpReg)
        call AddUnitBonus(.Owner, BONUS_STRENGTH, it.Str)
        call AddUnitBonus(.Owner, BONUS_AGILITY, it.Agi)
        call AddUnitBonus(.Owner, BONUS_INTELLIGENCE, it.Int)
        call AddUnitBonus(.Owner, BONUS_LIFE, it.Life)
        call AddUnitBonus(.Owner, BONUS_MANA, it.Mana)
        call AddUnitBonus(.Owner, BONUS_MOVEMENT_SPEED, it.Ms)
        if it.Effect != "" and it.EffectAttach != "" then
            set .fx[it.Slot] = AddSpecialEffectTarget(it.Effect, .Owner, it.EffectAttach)
        endif
        if it.Abil != 0 then
            call UnitAddAbility(.Owner, it.Abil)
        endif
    endmethod
    
    //removes the ItemStats for the hero
    private method removeItemStats takes Item it returns nothing
        call AddUnitBonus(.Owner, BONUS_ARMOR, - it.Armor)
        call AddUnitBonus(.Owner, BONUS_DAMAGE, - it.Dmg)
        call AddUnitBonus(.Owner, BONUS_ATTACK_SPEED, - it.As)
        call AddUnitBonus(.Owner, BONUS_LIFE_REGEN, - it.HpReg)
        call AddUnitBonus(.Owner, BONUS_MANA_REGEN_PERCENT, - it.MpReg)
        call AddUnitBonus(.Owner, BONUS_STRENGTH, - it.Str)
        call AddUnitBonus(.Owner, BONUS_AGILITY, - it.Agi)
        call AddUnitBonus(.Owner, BONUS_INTELLIGENCE, - it.Int)
        call AddUnitBonus(.Owner, BONUS_LIFE, - it.Life)
        call AddUnitBonus(.Owner, BONUS_MANA, - it.Mana)
        call AddUnitBonus(.Owner, BONUS_MOVEMENT_SPEED, - it.Ms)
        if it.Effect != "" and it.EffectAttach != "" then
            call DestroyEffect(.fx[it.Slot])
        endif
        if it.Abil != 0 then
            call UnitRemoveAbility(.Owner, it.Abil)
        endif
    endmethod
    
    //returns the slot of an item
    private method getItemSlot takes item it returns integer
        local item temp = null
        local integer i = 0
        loop
            set temp = UnitItemInSlot(.Owner, i)
            exitwhen i > 5 or temp == it
            set i = i + 1
        endloop
        set temp = null
        return i
    endmethod
        
    //Returns the first free Inventory slot of the hero
    private method getFreeSlot takes nothing returns integer
        local integer i = 0
        local integer free
        loop
            exitwhen i > 4
            if .items[i] == 0 then
                set free = i
            endif
            exitwhen .items[i] == 0
            set i = i + 1
        endloop
        return free
    endmethod
    
    //Returns the first free backpack slot of the hero
    private method getFreeBackpackSlot takes nothing returns integer
        local integer i = 0
        local integer free
        loop
            exitwhen i > 7
            if .backp[i] == 0 then
                set free = i
            endif
            exitwhen .backp[i] == 0
            set i = i + 1
        endloop
        return free
    endmethod
    
    //Returns the free place of the hero's backpack
    private method getBackpackPlace takes nothing returns integer
        local integer i = 0
        local integer i2 = 8
        loop
            exitwhen i > 7
            if .backp[i] != 0 then
                set i2 = i2 - 1
            endif
            set i = i + 1
        endloop
        return i2
    endmethod
    
    //Returns the free place of the hero's Inventory
    private method getInventoryPlace takes nothing returns integer
        local integer i = 0
        local integer i2 = 4
        loop
            exitwhen i > 3
            if .items[i] != 0 then
                set i2 = i2 - 1
            endif
            set i = i + 1
        endloop
        return i2
    endmethod
    
    //moves an item to the hero's backpack
    private method moveToBackpack takes item Moved, item Bag returns boolean
        local integer i = 0
        local integer id = GetItemTypeId(Moved)
        local integer Slot
        local Item it = Item.getItemById(id)
        if .getBackpackPlace() > 0 then
            loop
                exitwhen i > 7
                if .backp[i] == id and .bcharges[i] + GetItemCharges(Moved) <= MAX_ITEM_CHARGES and .bcharges[i] + GetItemCharges(Moved) <= it.MaxStacks and it.AllowStacks then
                    set .bcharges[i] = .bcharges[i] + GetItemCharges(Moved)
                    call RemoveItem(Bag)
                    call RemoveItem(Moved)                    
                    call UnitAddItemToSlotById(.Owner, BACKPACK_OPEN_ID, BACKPACK_SLOT)
                    call SetItemCharges(UnitItemInSlot(.Owner, BACKPACK_SLOT), .bfree)
                    return true
                endif
                set i = i + 1
            endloop
            set i = 0
            loop
                exitwhen i > 7
                if .backp[i] == 0 then
                    set .backp[i] = id
                    set .bcharges[i] = GetItemCharges(Moved)
                    set .bfree = .bfree - 1
                    call RemoveItem(Bag)
                    call RemoveItem(Moved)
                    call UnitAddItemToSlotById(.Owner, BACKPACK_OPEN_ID, BACKPACK_SLOT)
                    call SetItemCharges(UnitItemInSlot(.Owner, BACKPACK_SLOT), .bfree)
                    return true
                endif
                set i = i + 1
            endloop
        elseif .getBackpackPlace() <= 0 then
            set Slot = .getItemSlot(Moved)
            set i = GetItemCharges(Moved)
            call RemoveItem(Bag)
            call RemoveItem(Moved)      
            call UnitAddItemToSlotById(.Owner, BACKPACK_OPEN_ID, BACKPACK_SLOT)
            call SetItemCharges(UnitItemInSlot(.Owner, BACKPACK_SLOT), .bfree) 
            call UnitAddItemToSlotById(.Owner, id, Slot)
            call SetItemCharges(UnitItemInSlot(.Owner, Slot), i)
            call SimError(GetOwningPlayer(.Owner), "Backpack is full!")
            return false
        endif
        return false
    endmethod
    
    //moves an item from the first page to the second page
    private method moveToSecondPage takes item Moved, item Second returns boolean
        local integer i = 0
        local integer id = GetItemTypeId(Moved)
        local integer Slot
        loop
            exitwhen i > 3
            if .backp[i+4] == id and .bcharges[i+4] + GetItemCharges(Moved) <= MAX_ITEM_CHARGES and .bcharges[i+4] + GetItemCharges(Moved) <= Item.getItemById(GetItemTypeId(Moved)).MaxStacks then
                set .bcharges[i+4] = .bcharges[i+4] + GetItemCharges(Moved)
                call RemoveItem(Second)
                call RemoveItem(Moved)     
                call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_2, 4)
                return true
            endif
            set i = i + 1
        endloop
        
        set i = 0
        loop
            exitwhen i > 3
            if .backp[i+4] == 0 then
                set .backp[i+4] = id
                set .bcharges[i+4] = GetItemCharges(Moved)
                call RemoveItem(Second)
                call RemoveItem(Moved)
                call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_2, 4)
                return true
            endif
            set i = i + 1
        endloop
        
        set Slot = .getItemSlot(Moved)
        set i = GetItemCharges(Moved)
        call RemoveItem(Second)
        call RemoveItem(Moved)      
        call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_2, 4) 
        call UnitAddItemToSlotById(.Owner, id, Slot)
        call SetItemCharges(UnitItemInSlot(.Owner, Slot), i)
        call SimError(GetOwningPlayer(.Owner), "Cannot move item to a full page!")
        return false
    endmethod
    
    //moves an item from the second page to the first page
    private method moveToFirstPage takes item Moved, item First returns boolean
        local integer i = 0
        local integer id = GetItemTypeId(Moved)
        local integer Slot
        loop
            exitwhen i > 3
            if .backp[i] == id and .bcharges[i] + GetItemCharges(Moved) <= MAX_ITEM_CHARGES and .bcharges[i] + GetItemCharges(Moved) <= Item.getItemById(GetItemTypeId(Moved)).MaxStacks then
                set .bcharges[i] = .bcharges[i] + GetItemCharges(Moved)
                call RemoveItem(First)
                call RemoveItem(Moved)     
                call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_1, 4)
                return true
            endif
            set i = i + 1
        endloop
        
        set i = 0
        loop
            exitwhen i > 3
            if .backp[i] == 0 then
                set .backp[i] = id
                set .bcharges[i] = GetItemCharges(Moved)
                call RemoveItem(First)
                call RemoveItem(Moved)
                call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_1, 4)
                return true
            endif
            set i = i + 1
        endloop
        
        set Slot = .getItemSlot(Moved)
        set i = GetItemCharges(Moved)
        call RemoveItem(First)
        call RemoveItem(Moved)
        call UnitAddItemToSlotById(.Owner, BACKPACK_PAGE_1, 4) 
        call UnitAddItemToSlotById(.Owner, id, Slot)
        call SetItemCharges(UnitItemInSlot(.Owner, Slot), i)
        call SimError(GetOwningPlayer(.Owner), "Cannot move item to a full page!")
        return false
    endmethod
        
    //moves an item to the heroes inventory
    private method moveToInventory takes item Moved, item Close returns boolean
        local integer i = 0
        local integer id = GetItemTypeId(Moved)
        local integer Slot
        local Item it = Item.getItemById(id)
        set .allowauto = false
        if .getInventoryPlace() > 0 then
            loop
                exitwhen i > 3
                if .items[i] == id and .charges[i] + GetItemCharges(Moved) <= MAX_ITEM_CHARGES and .charges[i] + GetItemCharges(Moved) <= it.MaxStacks and it.AllowStacks then
                    set .charges[i] = .charges + GetItemCharges(Moved)
                    set .bfree = .bfree + 1
                    call RemoveItem(Close)
                    call RemoveItem(Moved)                    
                    call UnitAddItemToSlotById(.Owner, BACKPACK_CLOSE_ID, 5)
                    set .allowauto = true
                    return true
                endif
                set i = i + 1
            endloop
            
            set i = .getFreeSlot()
            set .items[i] = id
            set .charges[i] = GetItemCharges(Moved)
            set .bfree = .bfree + 1
            call RemoveItem(Close)
            call RemoveItem(Moved)
            call UnitAddItemToSlotById(.Owner, BACKPACK_CLOSE_ID, 5)
            set .allowauto = true
            return true
            
        elseif .getInventoryPlace() <= 0 then
            set Slot = .getItemSlot(Moved)
            set i = GetItemCharges(Moved)
            call RemoveItem(Close)
            call RemoveItem(Moved)      
            call UnitAddItemToSlotById(.Owner, BACKPACK_CLOSE_ID, 5)
            call UnitAddItemToSlotById(.Owner, id, Slot)
            call SetItemCharges(UnitItemInSlot(.Owner, Slot), i)
            call SimError(GetOwningPlayer(.Owner), "Inventory is full!")
            set .allowauto = true
            return false
        endif
        set .allowauto = true
        return false
    endmethod 
    
    //checks, if a hero can equip an item
    public method checkHero takes Item it, boolean UseError returns boolean
        if it.HeroClasses != "" then
            if not SearchString(it.HeroClasses, .HeroClass) then
                if UseError then
                    call SimError(GetOwningPlayer(.Owner), "Only " + it.HeroClasses + " can equip this item.")
                endif
                return false
            endif
        endif
        if it.ItemClass != "" then
            if not SearchString(.ItemClasses, it.ItemClass) then
                if UseError then
                    call SimError(GetOwningPlayer(.Owner), "This unit can't equip " + it.ItemClass + ".")
                endif
                return false
            endif
        endif
        if GetHeroLevel(.Owner) >= it.Level then
            return true
        else
            if UseError then
                call SimError(GetOwningPlayer(.Owner), "This item requires a hero level of " + I2S(it.Level) + " or greater.")
            endif
        endif
        return false
    endmethod
    
    //will be runned, whenever an item is used
    private static method useItem takes nothing returns boolean   
        local thistype this = .table[GetTriggerUnit()]
        local Item it = Item.getItemById(GetItemTypeId(GetManipulatedItem()))
        if GetItemTypeId(GetManipulatedItem()) == EQUIPMENT_OPEN_ID then
            return .openEquipment(GetTriggerUnit())
            
        elseif GetItemTypeId(GetManipulatedItem()) == BACKPACK_OPEN_ID then
            return .openBackpack(GetTriggerUnit())
            
        elseif GetItemTypeId(GetManipulatedItem()) == EQUIPMENT_CLOSE_ID or GetItemTypeId(GetManipulatedItem()) == BACKPACK_CLOSE_ID then
            if .open then
                return .closeEquipment(GetTriggerUnit())
            elseif .bopen then
                return .closeBackpack(GetTriggerUnit())
            endif
            
        elseif GetItemTypeId(GetManipulatedItem()) == EQUIPMENT_PAGE_1 or GetItemTypeId(GetManipulatedItem()) == EQUIPMENT_PAGE_2 or GetItemTypeId(GetManipulatedItem()) == BACKPACK_PAGE_1 or GetItemTypeId(GetManipulatedItem()) == BACKPACK_PAGE_2 then
            if .open then
                return .changePageEquipment(GetTriggerUnit())
            elseif .bopen then
                return .changePageBackpack(GetTriggerUnit())
            endif
            
        elseif it.Equipment and not .isItemEquipped(GetManipulatedItem()) then
            return .equipItem(GetTriggerUnit(), GetManipulatedItem(), it)
        elseif it.Equipment and .isItemEquipped(GetManipulatedItem()) and .open then
            return .unequipItem(GetTriggerUnit(), GetManipulatedItem(), it)
        endif
        
        return false
    endmethod
    
    //Will be runned, whenever an item is dragged on another item or on an empty slot
    private static method dragItem takes nothing returns boolean
        local item manipul = GetOrderTargetItem()
        local integer slot = GetIssuedOrderId() - 852002
        local thistype this = .table[GetTriggerUnit()]
        local item dropped = UnitItemInSlot(.Owner, slot)
        local integer id = GetItemTypeId(manipul)
        local integer idd = GetItemTypeId(dropped)
        
        if (GetIssuedOrderId() > 852001) and (GetIssuedOrderId() < 852008) and this != 0 then
        
            if manipul != dropped and id != BACKPACK_PAGE_1 and id != BACKPACK_PAGE_2 and id != BACKPACK_CLOSE_ID and id != BACKPACK_OPEN_ID then
                
                if idd == BACKPACK_OPEN_ID then
                    set .dropped = false
                    call .moveToBackpack(manipul, dropped)
                    set .dropped = true
                    set manipul = null
                    set dropped = null
                    return false
                    
                elseif idd == BACKPACK_CLOSE_ID then
                    set .dropped = false
                    call .moveToInventory(manipul, dropped)
                    set .dropped = true
                    set manipul = null
                    set dropped = null
                    return false
                    
                elseif idd == BACKPACK_PAGE_2 then
                    set .dropped = false
                    call .moveToSecondPage(manipul, dropped)
                    set .dropped = true
                    set manipul = null
                    set dropped = null
                    return false
                    
                elseif idd == BACKPACK_PAGE_1 then
                    set .dropped = false
                    call .moveToFirstPage(manipul, dropped)
                    set .dropped = true
                    set manipul = null
                    set dropped = null
                    return false
                endif
            endif
        endif
        
        if id == BACKPACK_OPEN_ID or id == BACKPACK_CLOSE_ID or id == BACKPACK_PAGE_1 or id == BACKPACK_PAGE_2 and dropped == null then
            
            if id == BACKPACK_OPEN_ID and not .bopen and not .open then
                call SimError(GetOwningPlayer(.Owner), "Cannot drop this item.")
                call addItem.create(manipul, BACKPACK_SLOT, this)
                set manipul = null
                set dropped = null
                return false
                
            elseif id == BACKPACK_CLOSE_ID or id == BACKPACK_PAGE_1 or id == BACKPACK_PAGE_2 and .bopen then
                call SimError(GetOwningPlayer(.Owner), "Cannot drop this item.")
                if id == BACKPACK_CLOSE_ID then
                    call addItem.create(manipul, 5, this)
                elseif id == BACKPACK_PAGE_1 or id == BACKPACK_PAGE_2 then
                    call addItem.create(manipul, 4, this)
                endif
                set manipul = null
                set dropped = null
                return false
            endif
        endif
        
        if (id == BACKPACK_PAGE_1 or id == BACKPACK_PAGE_2) and idd == BACKPACK_CLOSE_ID and .bopen then
            call SimError(GetOwningPlayer(.Owner), "Cannot drop this item.")
            call addItem.create(manipul, 4, this)  
            call addItem.create(dropped, 5, this)
            set manipul = null
            set dropped = null
            return false
            
        elseif id == BACKPACK_CLOSE_ID and (idd == BACKPACK_PAGE_1 or idd == BACKPACK_PAGE_2) and .bopen then        
            call SimError(GetOwningPlayer(.Owner), "Cannot drop this item.")
            call addItem.create(manipul, 5, this)  
            call addItem.create(dropped, 4, this)
            set manipul = null
            set dropped = null
            return false
            
        endif        
        set manipul = null
        set dropped = null
        return true
    endmethod
    
    //will be runned whenever an item is picked up
    private static method pickupItem takes nothing returns boolean
        local thistype this = .table[GetTriggerUnit()]
        local item i = GetManipulatedItem()
        local Item it = Item.getItemById(GetItemTypeId(i))
        
        if AUTO_EQUIP and it.Equipment and .isSlotEmpty(it.Slot) and .checkHero(it, false) and .allowauto then        
            call thistype.equipItem(GetTriggerUnit(), GetManipulatedItem(), it)
            set i = null
            return true
        endif
        
        return false
    endmethod
    
    //Will be runned whenever an item is dropped
    private static method dropItem takes nothing returns boolean
        local thistype this = .table[GetTriggerUnit()]
        local item ite = GetManipulatedItem()
        local integer id = GetItemTypeId(ite)
        if this == 0 or ite == null or not .dropped then
            return false
            
        elseif this != 0 and ite != null and .dropped then
        
            if id == BACKPACK_OPEN_ID and not .bopen and not .open then
                call SimError(GetOwningPlayer(.Owner), "Cannot drop this item.")
                call addItem.create(ite, BACKPACK_SLOT, this)
                set ite = null
                return true
                
            elseif id == BACKPACK_CLOSE_ID or id == BACKPACK_PAGE_1 or id == BACKPACK_PAGE_2 and (.bopen or .open) then
                
                if id == BACKPACK_CLOSE_ID then
                    call SimError(GetOwningPlayer(.Owner), "Cannot drop this item.")
                    call addItem.create(ite, 5, this)
                    set ite = null
                    return true
                    
                elseif id == BACKPACK_PAGE_1 or id == BACKPACK_PAGE_2 then
                    call SimError(GetOwningPlayer(.Owner), "Cannot drop this item.")
                    call addItem.create(ite, 4, this)
                    set ite = null
                    return true
                endif
            endif
        endif
        return false
    endmethod
    
    private static trigger Use = CreateTrigger()
    private static trigger Pickup = CreateTrigger()
    private static trigger Drag = CreateTrigger()
    private static trigger Drop = CreateTrigger()
    
    //initialization of the Inventory struct
    private static method onInit takes nothing returns nothing
        call TriggerAddCondition(.Use, Condition(function thistype.useItem))
        call TriggerAddCondition(.Pickup, Condition(function thistype.pickupItem))
        call TriggerAddCondition(.Drag, Condition(function thistype.dragItem))
        call TriggerAddCondition(.Drop, Condition(function thistype.dropItem))
        
        set .table = HandleTable.create()
        call SETUP_DUMMY_ITEMS()
    endmethod
    
endstruct
    
endlibrary
 
Level 13
Joined
Jul 26, 2008
Messages
1,009
The test map works perfectly. The items stack when picked up and they can be grabbed off the ground in the test map.

When placed in my map, it becomes buggy. The pick-up trigger is what I'm looking at to figure this out. Or even if someone could help me reinvent the pick-up trigger to work with my map that'd be appreciated.

The thing about this system is that Vuen's is such a unique map very very few custom inventory systems will work with it. This is probably one of the best ones I've found, with the exception of this problem.

For an inventory system to work, it would need to be MUI and controllable for Players who have shared control. Further it would need to be customizable and setable for heroes who do not have the inventory system yet.

This system is perfect for Vuen's. It allows DMs to use typed strings to set the inventory specifications.= when applying the inventory.

The issue is likely a system in my map, but I'm uncertain which. I have XE, CS, Rising Dusk Knockback, Terrain Pathability, Last Order, Table, AutoIndex (Which the newest version seems to want to conflict with this system though it relies on an older version), Group Utils, Timer Utils. It's a lot of systems, but none of them seem like they'd conflict with the inventorysystem.

I'm trying to figure out what's wrong with the pick-up trigger and possibly the stack detection trigger. :\ They are having problems in my map primarily.
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
The script you posted is almost 1500 lines. Nobody is going to review an enormous system like this because you can't get it to work. A well made inventory system should be usable. If it isn't usable, then you need to move on and use a different system - I for one don't want to spend 30-40 minutes reading through a 3rd-party library for problems.
 
Status
Not open for further replies.
Top