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

MUI Multiboard Inventory/Equipment System v.6.0

  • Like
Reactions: lobster and Spet
This is my Multiboard Inventory and Equipment System, requested by vercas

with this system you are able to give as much units as you want a multiboard inventory.
the multiboard stays hidden until you open it.

to add an item activate autoadd and pick it up or right-click on the item in your normal inventory and then click on the inventory item to add it...

it includes a equipment system which is in the multiboard, too.
you can navigate in there by using the arrow keys.
you are able to:
- add a unique inventory to each unit
- drop items to the normal inventory
- add items to the multiboard inventory
- equip equipable items
- unequip them ;)

complete in vJass and MUI...
you'll need the JNGP to edit/save the map

have fun^^


UPDATE v2.0: Changed the code a little, nulled some locals i forgot, made the code better
readable^^ and the inventory now opens and closes with one ability/hotkey.
I also added some customizable things...

Update v3.0: System is now 1.24 compatible, so some changes made in the code

Update v4.0: Fixed a bug opening an inventory multiboard for all players
added function to maually enable/disable autoadd
added a boolean for hiding the autoadd ability

Update v5.0: Removed the useless O(n) searches and added hashtables. also small performance improvements.
also replaced a local group variable with a global one

Update v6.0: No really all useless O(n) searches are gone and extended hashtable usage.
in addition corrected some typing mistakes


JASS:
library MultiboardInventory initializer Init

// The_Witcher's Multiboard Equipment and Inventory System
//
//This is a MUI inventory-in-a-multiboard-system.
//it allows you to add an inventory to any unit
//the inventory has a part for equipment and a part for a "normal" inventory
//you can register items for this system (unregistered ones won't move inside the inventory),
//check whether a unit has a item of type xy in its inventory, force dropping of an item of type, 
//directly remove a item of type xy from the iventory from the game or check whether a itemtype is already registered
//
// when you give a unit a inventory it will only open when you cast the open ability. you can navigate with the arrow keys.
// items with charges will stack automatically. to add an item right click on it and the right click again on the "Inventory" item.
// when autoadd is enabled all pickuped items which are registered will be added automatically
//
// here are the included functions:
//
// 1.to give a unit the inventory use
//
//  call InitInventory(ToWhichUnit)
//                        unit    
//
// 2.To get rid of a inventory just use
//   call DestroyInventory( which unit's)
//                             unit
//
// 3.to register an item for this system use(if the item shouldn't be equipable enter 0 for UsedSlotWhenEquipment. the abilities can be 0 then, too.)
//  call RegisterItem(itemid, ItemDescription, PathToIcon, ability1, ability2, ability3, UsedSlotWhenEquipment)
//                   integer     string          string    integer   integer   integer        integer
//
// 4.to check whether you have an item already registered use(it will return true or false)
//   call IsItemRegistered(itemid)
//                        integer
//
// 5.to force dropping of a item use (it will drop the first found item of that type)
//   call DropItemById(fromWhich, itemid) 
//                       unit     integer
//
// 6.to remove an item directly use ( it will remove the first found item of that type)
//   call RemoveItemById(FromWhichUnit, itemid)
//                          unit        integer
//
// 7.to check whether a unit has an item of type xy use
//   call UnitHasItemOfId(WhichUnit, itemid)
//                          unit     integer
//
// 8.to change the description of a registered itemtype use
//   call ChangeItemDescription(itemid, newdescription)
//                              integer   string
//
// 9.to manually enable/disable the auto add for a specific unit use
//   call ForceAutoAdd(forwhich, flag)
//                       unit   boolean
//
// to implement this system, just copy this trigger in your map
// it requires jngp to be edited/saved
//
// have fun^^
//
//--------------------------------
//--------The SETUP PART----------
//--------------------------------

globals
    private constant integer openabi = 'A000'           // the ability to open/close the inventory
    private constant integer dropabi = 'A002'           // the ability to drop the selected item to the normal inventory
    private constant integer equipabi = 'A003'          // the ability to equip the selected item
    private constant integer autoadd = 'A005'           // the ability to enable/disable autoadd
    private constant integer inventitem = 'I000'        // the rawcode of the invetory item you use to add single items
    private constant string emptyslot = "[------]"      // the text shown when a slot is not used
    private constant string NewLine = "PP"              // the text used in the description to show the parser that he should start a new line (\n will NOT work)
    private constant string name = "|cff0863B5"         // the colorcode of the Name of the selected item in the info part
    private constant string description = "|cff08B5FF"  // the colorcode of the description of the selected item in the info part
    private constant string help = "|cffE62929"         // the colorcode of the help texts
    private constant string titles = "|cffFFCC00"       // the colorcode of the names of the cathegories
    private constant integer classes = 8                // the amount of different classes you have for equipable items
    private constant boolean autoadd_enabled = true     // if this is false units won't get the autoadd ability. autoadd is only possible by functions then.
    
                        //make sure that you synch the following hotkey variables with the hotkeys of the abilities in the object editor
    private constant string HotkeyExit = "O"            // the hotkey for opening/closing the multiboard inventory
    private constant string HotkeyDrop = "D"            // the hotkey for dropping an item
    private constant string HotkeyEquip = "E"           // the hotkey for equiping/unequiping an item
    private constant string HotkeyAutoadd = "T"         // the hotkey for Enabling/Disabling the AutoAdd feature
    
    private string array EquipName             // ignore this one here
endglobals

private function InitItems takes nothing returns nothing  // use this function to register all the items you want to be registered from the start
    // potion
    call RegisterItem.evaluate('phea',"Heals very good, and is very healthy...","ReplaceableTextures\\CommandButtons\\BTNPotionGreenSmall.blp",0,0,0,0)
    // clear vision
    call RegisterItem.evaluate('plcl',"For clear vision.PPEnables best underwaterview ever seen.PPAlso is very userfriendly!!!","ReplaceableTextures\\CommandButtons\\BTNLesserClarityPotion.blp",0,0,0,0)
    // sword
    call RegisterItem.evaluate('I001',"This is just a normal sword!PP PPType: Mainhand.PPAdds 5 Damage.","ReplaceableTextures\\CommandButtons\\BTNDaggerOfEscape.blp",'A004',0,0,2)
    // big sword
    call RegisterItem.evaluate('I002',"This sword is very huge!PPIt deals epic damage!!PP PPType: Mainhand.PPAdds 20 Damage.","ReplaceableTextures\\CommandButtons\\BTNArcaniteMelee.blp",'A006',0,0,2)
    // big shield
    call RegisterItem.evaluate('I003',"A heavy shield. Helping even against strong blows.PP PPType: Offhand.PPAdds 10 Armor.","ReplaceableTextures\\CommandButtons\\BTNHumanArmorUpThree.blp",'A007',0,0,3)
    // shield
    call RegisterItem.evaluate('I004',"A small shield. Helps only against light blows.PP PPType: Offhand.PPAdds 3 Armor.","ReplaceableTextures\\CommandButtons\\BTNHumanArmorUpOne.blp",'A008',0,0,3)
    // cursed armor
    call RegisterItem.evaluate('I005',"This Armor is cursed and will help you, boosting your defensive and offensive skillsPP PPType: Armor.PPAdds 3 Armor and 4 damage.","ReplaceableTextures\\CommandButtons\\BTNMoonArmor.blp",'A009','A00A',0,4)
    // special box
    call RegisterItem.evaluate('I006',"Huh? A small box with a paper in it:PP PPThis System is created by The_Witcher!!","ReplaceableTextures\\CommandButtons\\BTNBox.blp",0,0,0,8)
endfunction

private function InitEquipment takes nothing returns nothing   // use this function to set up the names of the equipment slots
    set EquipName[1] = "[Helmet]"
    set EquipName[2] = "[Mainhand]"
    set EquipName[3] = "[Offhand]"
    set EquipName[4] = "[Armor]"
    set EquipName[5] = "[Boots]"
    set EquipName[6] = "[Gloves]"
    set EquipName[7] = "[Amulet]"
    set EquipName[8] = "[Special]"
endfunction

//--------------------------------
//---------END OF SETUP-----------
//--------------------------------

globals
    private integer items = 1
    private integer array itemm
    private string array text
    private string array iconpath
    private integer array abi1
    private integer array abi2
    private integer array abi3
    private integer array slot
    private integer array x
    private integer array y
    private group g = CreateGroup()
    private multiboard array board
    private unit array t
    private integer maxchars = 35
    private hashtable h = InitHashtable()
    private group d =CreateGroup()
endglobals    

function RegisterItem takes integer itemid, string description, string path, integer abil1, integer abil2, integer abil3, integer slott returns nothing
    set items = items + 1
    call SaveInteger(h,itemid,0,items)
    set itemm[items] = itemid
    set text[items] = description
    set iconpath[items] = path
    set abi1[items] = abil1
    set abi2[items] = abil2
    set abi3[items] = abil3
    set slot[items] = slott + 1
endfunction

function ChangeItemDescription takes integer itemid, string newdescr returns nothing
    set text[LoadInteger(h,itemid,0)] = newdescr
endfunction  


private struct data
    unit u
    multiboard m
    integer lu = 1
    item invent
    boolean auto = false
    integer array stack[99]
    integer array slot2index[99]
endstruct

private function ParseString takes string toparse, integer i returns nothing
    local integer s = 0
    local integer line = 0
    local integer linestart = 0
    local integer spacepoint = 0
    local boolean next = false
    loop
        exitwhen s > 28
        call MultiboardSetItemValueBJ( board[i], 2, 9+s, "")
        set s = s+ 1
    endloop
    set s = 0
    loop
        exitwhen linestart+s > StringLength(toparse)
        set s = s+1
        if SubString(toparse,linestart+s-1,linestart+s) == " " then
            set spacepoint = linestart+s
        endif
        if SubString(toparse,linestart+s-StringLength(NewLine),linestart+s) == NewLine then
            set spacepoint = linestart+s-StringLength(NewLine)
            set s = maxchars
            set next = true
        endif
        if s >= maxchars then
            call MultiboardSetItemValueBJ( board[i], 2, 9+line, description + SubString(toparse,linestart,spacepoint ) + "|r" )
            set linestart = spacepoint
            set spacepoint = linestart
            set s = 0
            set line = line + 1
            if next then
                set next = false
                set linestart = linestart + StringLength(NewLine)
            endif
        endif
    endloop
    call MultiboardSetItemValueBJ( board[i], 2, 9+line, description + SubString(toparse,linestart,StringLength(toparse) ) + "|r" )
endfunction

private function UpdateDescription takes integer i returns nothing
    local item ite
    local integer a = 2
    local data dat = LoadInteger(h,GetHandleId(t[i]),1)     
    if dat == 0 then
        return
    endif
    loop 
        exitwhen a > 28
        if dat.slot2index[a] != 0 then
            call MultiboardSetItemColorBJ(dat.m,3,a,100,100,100,0)
            call MultiboardSetItemColorBJ(dat.m,4,a,100,100,100,0)
        else
            call MultiboardSetItemColorBJ(dat.m,3,a,50,50,50,0)
            call MultiboardSetItemColorBJ(dat.m,4,a,50,50,50,0)
        endif
        set a = a + 1
    endloop
    set a = 30
    loop 
        exitwhen a > 56
        if dat.slot2index[a] != 0 then
            call MultiboardSetItemColorBJ(dat.m,1,a-28,100,100,100,0)
        else
            call MultiboardSetItemColorBJ(dat.m,1,a-28,50,50,50,0)
        endif
        set a = a + 1
    endloop
    if x[i] == 1 then
        call MultiboardSetItemColorBJ( dat.m, 1, y[i], 10, 100, 10, 0 )
    else
        call MultiboardSetItemColorBJ( dat.m, 3, y[i], 10, 100, 10, 0 )
        call MultiboardSetItemColorBJ( dat.m, 4, y[i], 10, 100, 10, 0 )
    endif
    if x[i] == 1 then
        set ite = CreateItem(itemm[dat.slot2index[y[i] + 28]],0,0)               
        call MultiboardSetItemValueBJ( dat.m, 2, 8, name + GetItemName(ite) + "|r" )
        call RemoveItem(ite)
        set ite = null
        call ParseString(text[dat.slot2index[y[i] + 28]],i)
    else
        set ite = CreateItem(itemm[dat.slot2index[y[i]]],0,0)
        call MultiboardSetItemValueBJ( dat.m, 2, 8, name + GetItemName(ite) + "|r"  )
        call RemoveItem(ite)
        set ite = null
        call ParseString(text[dat.slot2index[y[i]]],i)
    endif
endfunction

private function AddItem takes item which, data dat returns nothing
    local integer i = LoadInteger(h,GetItemTypeId(which),0)
    local integer a = 0
    local boolean b
    if which == null then
        return
    endif
    loop
        exitwhen a > dat.lu
        if itemm[dat.slot2index[a]] == GetItemTypeId(which) and GetItemCharges(which)!= 0 and dat.stack[a] < 99 then
            set dat.stack[a] = dat.stack[a] + GetItemCharges(which)
            call MultiboardSetItemValueBJ( dat.m, 4, a, I2S(dat.stack[a]) )
            call RemoveItem(which)
            return
        endif
        set a = a + 1
    endloop
    if dat.lu != 28 then
        set dat.lu = dat.lu + 1
        set dat.slot2index[dat.lu] = i
        set dat.stack[dat.lu] = GetItemCharges(which)
        call MultiboardSetItemStyleBJ( dat.m, 3, dat.lu, true, true )
        call MultiboardSetItemIconBJ( dat.m, 3, dat.lu, iconpath[i] )
        call MultiboardSetItemValueBJ( dat.m, 3, dat.lu, GetItemName(which) )
        if dat.stack[dat.lu]!= 0 then
            call MultiboardSetItemValueBJ( dat.m, 4, dat.lu, I2S(dat.stack[dat.lu]) )
        endif
        call RemoveItem(which)
    endif     
    call UpdateDescription(GetPlayerId(GetOwningPlayer(dat.u)))
endfunction

private function InventoryRemoveItem takes integer i, data dat returns nothing
    local integer k = y[i]
    local item ite
    if (x[i] == 3 and k > dat.lu) or (x[i] == 1 and dat.slot2index[k+28] == 0)then     
        return
    endif
    if x[i] == 1 then
        call UnitRemoveAbility(dat.u,abi1[dat.slot2index[k+28]])
        call UnitRemoveAbility(dat.u,abi2[dat.slot2index[k+28]])
        call UnitRemoveAbility(dat.u,abi3[dat.slot2index[k+28]])
        set dat.slot2index[k+28] = 0
        call MultiboardSetItemValueBJ( dat.m, 1, k, EquipName[k-1] )
        call MultiboardSetItemStyleBJ( dat.m, 1, k, true, false )
    else
        loop
            call MultiboardSetItemIconBJ( dat.m, 3, k, iconpath[dat.slot2index[k+1]] )
            set ite = CreateItem(itemm[dat.slot2index[k+1]],0,0)
            call MultiboardSetItemValueBJ( dat.m, 3, k, GetItemName(ite) )
            if dat.stack[k+1]!= 0 then
                call MultiboardSetItemValueBJ( dat.m, 4, k, I2S(dat.stack[k+1]) )
            else  
                call MultiboardSetItemValueBJ( dat.m, 4, k, "" )
            endif
            set dat.stack[k] = dat.stack[k+1]
            call RemoveItem(ite)
            set dat.slot2index[k] = dat.slot2index[k+1]
            exitwhen k == dat.lu
            set k = k + 1
        endloop
        call MultiboardSetItemStyleBJ( dat.m, 3, dat.lu, true, false )
        call MultiboardSetItemValueBJ( dat.m, 3, dat.lu, emptyslot )
        call MultiboardSetItemValueBJ( dat.m, 4, dat.lu, "" )
        set dat.slot2index[dat.lu] = 0
        set dat.stack[dat.lu] = 0
        set dat.lu = dat.lu - 1
    endif
    set ite = null
    call UpdateDescription(i)
endfunction

private function Unequip takes integer i,integer slot, data dat returns nothing
    local integer k = slot
    local item ite
    if itemm[dat.slot2index[k+28]] == 0 then
        return
    endif
    set ite = CreateItem(itemm[dat.slot2index[k+28]],0,0)
    call AddItem(ite,dat)
    call UnitRemoveAbility(dat.u,abi1[dat.slot2index[k+28]])
    call UnitRemoveAbility(dat.u,abi2[dat.slot2index[k+28]])
    call UnitRemoveAbility(dat.u,abi3[dat.slot2index[k+28]])
    set dat.slot2index[k+28] = 0
    call MultiboardSetItemValueBJ( dat.m, 1, k, EquipName[k-1] )
    call MultiboardSetItemStyleBJ( dat.m, 1, k, true, false )
    call UpdateDescription(i)
    set ite = null
endfunction

private function Equip takes integer i, data dat returns nothing
    local integer k = y[i]
    local item ite
    if k > dat.lu or slot[dat.slot2index[k]] == 1 then
        return
    endif
    if dat.slot2index[slot[dat.slot2index[y[i]]]+28] != 0 then
        set k = slot[dat.slot2index[k]]
        set ite = CreateItem(itemm[dat.slot2index[k+28]],0,0)
        call AddItem(ite,dat)
        call UnitRemoveAbility(dat.u,abi1[dat.slot2index[k+28]])
        call UnitRemoveAbility(dat.u,abi2[dat.slot2index[k+28]])
        call UnitRemoveAbility(dat.u,abi3[dat.slot2index[k+28]])
        set dat.slot2index[k+28] = 0
        call MultiboardSetItemValueBJ( dat.m, 1, k, EquipName[k-1] )
        call MultiboardSetItemStyleBJ( dat.m, 1, k, true, false )
        set k = y[i]
    endif
    set dat.slot2index[slot[dat.slot2index[k]]+28] = dat.slot2index[k]
    set ite = CreateItem(itemm[dat.slot2index[k]],0,0)
    call MultiboardSetItemValueBJ( dat.m, 1, slot[dat.slot2index[k]], GetItemName(ite) )
    call MultiboardSetItemIconBJ( dat.m, 1, slot[dat.slot2index[k]], iconpath[dat.slot2index[k]] )
    call MultiboardSetItemStyleBJ( dat.m, 1, slot[dat.slot2index[k]], true, true )
    call RemoveItem(ite)
    call UnitAddAbility(dat.u,abi1[dat.slot2index[k]])
    call UnitAddAbility(dat.u,abi2[dat.slot2index[k]])
    call UnitAddAbility(dat.u,abi3[dat.slot2index[k]])
    set ite = null
    call InventoryRemoveItem(i,dat)
endfunction

function IsItemRegistered takes integer itemid returns boolean
     return LoadInteger(h,itemid,0) != 0
endfunction

function InitInventory takes unit u returns nothing
    local integer i = 2
    local data dat = data.create()
    set dat.u = u
    set dat.m = CreateMultiboardBJ(4,30,"Inventory")
    call MultiboardSetItemWidthBJ( dat.m, 1, 0, 25 )
    call MultiboardSetItemWidthBJ( dat.m, 2, 0, 22 )
    call MultiboardSetItemWidthBJ( dat.m, 3, 0, 25 )
    call MultiboardSetItemWidthBJ( dat.m, 4, 0, 8 )
    call MultiboardSetItemStyleBJ( dat.m, 0, 0, true, false )
    call MultiboardSetItemValueBJ( dat.m, 3, 0, emptyslot )
    call MultiboardSetItemValueBJ( dat.m, 3, 29, "" )
    call MultiboardSetItemValueBJ( dat.m, 3, 30, "" )
    call MultiboardSetItemValueBJ( dat.m, 3, 1, titles + "INVENTORY" + "|r")
    call MultiboardSetItemValueBJ( dat.m, 1, 1, titles + "EQUIPMENT" + "|r")
    call MultiboardSetItemValueBJ( dat.m, 2, 7, titles + "INFO" + "|r" )
    call MultiboardSetItemValueBJ( dat.m, 2, 1, titles + "HELP" + "|r" )
    call MultiboardSetItemValueBJ( dat.m, 4, 1, titles + "CHARGES" + "|r" )
    call MultiboardSetItemValueBJ( dat.m, 2, 2, help + HotkeyExit +" = Exit" + "|r")
    call MultiboardSetItemValueBJ( dat.m, 2, 3, help + HotkeyDrop +" = Drop to normal Inventory" + "|r")
    call MultiboardSetItemValueBJ( dat.m, 2, 4, help + HotkeyEquip +" = Equip/Unequip"  + "|r")
    call MultiboardSetItemValueBJ( dat.m, 2, 5, help + HotkeyAutoadd +" = AutoPickup ON/OFF  [OFF]"  + "|r")
    loop
        exitwhen i == classes+2
        call MultiboardSetItemValueBJ( dat.m, 1, i, EquipName[i-1] )
        set i = i + 1
    endloop
    call MultiboardDisplay(dat.m,false)
    call UnitAddAbility(u,openabi)
    if autoadd_enabled then
        call UnitAddAbility(u,autoadd)
    endif
    call UnitRemoveItemFromSlot(u,5)
    call UnitAddItemToSlotById(u,inventitem,5)
    set dat.invent = UnitItemInSlot(u,5)
    call GroupAddUnit(g,u)
    call SaveInteger(h,GetHandleId(u),1,dat)
endfunction

function DestroyInventory takes unit u returns boolean
    local data dat = LoadInteger(h,GetHandleId(u),1)
    local integer i = 0
    if dat == 0 then
        return false
    endif
    call MultiboardDisplay(dat.m,false)
    call UnitRemoveAbility(u,openabi)
    call UnitRemoveAbility(u,autoadd)
    call UnitRemoveAbility(u,dropabi)
    call UnitRemoveAbility(u,equipabi)
    call UnitRemoveItemFromSlot(u,5)
    call GroupRemoveUnit(g,u)
    call FlushChildHashtable(h,GetHandleId(u))
    call dat.destroy()
    return true
endfunction

private function abilities takes nothing returns nothing
    local data dat
    local unit u = GetTriggerUnit()
    local integer i = GetPlayerId(GetOwningPlayer(u))
    local boolean b
    if (GetSpellAbilityId() == openabi) then
        set dat = LoadInteger(h,GetHandleId(u),1)
        if board[i] != null then
            call MultiboardDisplay(board[i],false)
            call UnitRemoveAbility(u,dropabi)
            call UnitRemoveAbility(u,equipabi)
            set board[i] = null
            set t[i] = null
        else
            set x[i] = 3
            set y[i] = 2
            if GetLocalPlayer() == Player(i) then
                call MultiboardDisplay(dat.m,true)
                call MultiboardMinimize(dat.m, false)
            endif
            set board[i] = dat.m
            set t[i] = dat.u
            call UnitAddAbility(u,dropabi)
            call UnitAddAbility(u,equipabi)
            call UpdateDescription(i)
        endif
    elseif (GetSpellAbilityId() == dropabi) then
        set dat = LoadInteger(h,GetHandleId(u),1)
        set b = dat.auto
        set dat.auto = false
        if x[i] == 3 then
            if dat.stack[y[i]]!=0 then
                call SetItemCharges(UnitAddItemById(dat.u, itemm[dat.slot2index[y[i]]]),dat.stack[y[i]])
            else
                call UnitAddItemById(dat.u, itemm[dat.slot2index[y[i]]])
            endif
        else
            call UnitAddItemById(dat.u, itemm[dat.slot2index[y[i]+28]])
        endif
        call InventoryRemoveItem(i,dat)
        set dat.auto = b
    elseif (GetSpellAbilityId() == equipabi) then
        set dat = LoadInteger(h,GetHandleId(u),1)
        if x[i] == 1 then
            call Unequip(i,y[i], dat)
        else
            call Equip(i, dat)
        endif
    elseif (GetSpellAbilityId() == autoadd) then
        set dat = LoadInteger(h,GetHandleId(u),1)
        if dat.auto == false then
            set dat.auto = true
            call MultiboardSetItemValueBJ( dat.m, 2, 5, help + "T = AutoPickup ON/OFF  [ON]"  + "|r")
        else
            set dat.auto = false
            call MultiboardSetItemValueBJ( dat.m, 2, 5, help + "T = AutoPickup ON/OFF  [OFF]"  + "|r")
        endif
    endif
    set u = null
endfunction

private function AddingItemsAndMultiboardStuff takes nothing returns nothing
    local data dat
    local unit u
    local item ite
    local boolean b
    local integer i = 0
    loop
        exitwhen i > bj_MAX_PLAYER_SLOTS
        if board[i] != null then
        if IsUnitSelected(t[i],Player(i)) == false then
            set dat = LoadInteger(h,GetHandleId(t[i]),1)
            call MultiboardDisplay(dat.m,false)
            set board[i] = null
            call UnitRemoveAbility(dat.u,dropabi)
            call UnitRemoveAbility(dat.u,equipabi)
            set t[i] = null
        endif
        if IsMultiboardMinimized(board[i]) and board[i] != null then
            call MultiboardMinimize(board[i],false)
        endif
        endif
        set i = i + 1
    endloop
    call GroupAddGroup(g,d)
    loop
        set u = FirstOfGroup(d)
        exitwhen u == null
        set ite = UnitItemInSlot(u,5)
        if GetItemTypeId(ite) != inventitem then
            if IsItemRegistered(GetItemTypeId(ite)) then
                set dat = LoadInteger(h,GetHandleId(u),1)
                if dat.lu == 28 then
                    call UnitRemoveItem(u,ite)
                endif
                call AddItem(ite,dat)
                call RemoveItem(dat.invent)
                call UnitAddItemToSlotById(u,inventitem,5)
                set dat.invent = UnitItemInSlot(u,5)
                if ite != null then
                    call UnitAddItem(u,ite)
                endif
            else
                set dat = LoadInteger(h,GetHandleId(u),1)
                set b = dat.auto
                set dat.auto = false
                set ite = UnitRemoveItemFromSlot(dat.u,5)
                call RemoveItem(dat.invent)
                call UnitAddItemToSlotById(u,inventitem,5)
                set dat.invent = UnitItemInSlot(u,5)
                call UnitAddItem(dat.u,ite)
                set dat.auto = b
            endif
        endif
        call GroupRemoveUnit(d,u)
    endloop
    set ite = null
endfunction

function UnitHasItemOfId takes unit u, integer itemid returns boolean
     local data dat = LoadInteger(h,GetHandleId(u),1)
     local integer a = 0
     if dat == 0 then
        return false
     endif
     loop
        exitwhen a == 56
        if itemm[dat.slot2index[a]] == itemid then
            return true
        endif
        set a = a + 1
    endloop
    return false
endfunction

private function GetXOfItemOfId takes unit u, integer itemid returns integer
     local data dat = LoadInteger(h,GetHandleId(u),1)
     local integer a = 0
     loop
        exitwhen a == 56
        if itemm[dat.slot2index[a]] == itemid then
            if a > 28 then
            return 1
            endif
            return 3
        endif
        set a = a + 1
    endloop
    return 0
endfunction

private function GetYOfItemOfId takes unit u, integer itemid returns integer
     local data dat = LoadInteger(h,GetHandleId(u),1)
     local integer a = 0
     loop
        exitwhen a == 56
        if itemm[dat.slot2index[a]] == itemid then
            if a > 28 then
            return a-28
            endif
            return a
        endif
        set a = a + 1
    endloop
    return 0
endfunction

function DropItemById takes unit fromwhich, integer itemid returns item
    local data dat = LoadInteger(h,GetHandleId(fromwhich),1)
    local item ite
    local integer i = GetPlayerId(GetOwningPlayer(dat.u))
    local boolean b
    local integer xx = x[i]
    local integer yy = y[i]
    if dat == 0 then
        return null
    endif
    set b = dat.auto
    set dat.auto = false
    set x[i] = GetXOfItemOfId(dat.u,itemid)
    set y[i] = GetYOfItemOfId(dat.u,itemid)
    if x[i] != 0 and y[i] != 0 then
        if x[i] == 3 then
            if dat.stack[y[i]]!=0 then
                set ite = UnitAddItemById(dat.u, itemm[dat.slot2index[y[i]]])
                call SetItemCharges(ite,dat.stack[y[i]])
            else
                set ite = UnitAddItemById(dat.u, itemm[dat.slot2index[y[i]]])
            endif
        else
            set ite = UnitAddItemById(dat.u, itemm[dat.slot2index[y[i]+28]])
        endif
        call InventoryRemoveItem(i, dat)
    endif
    set dat.auto = b
    set x[i] = xx
    set y[i] = yy
    return ite
endfunction

function RemoveItemById takes unit fromwhich, integer itemid returns nothing
    local data dat = LoadInteger(h,GetHandleId(fromwhich),1)
    if dat == 0 then
        return
    endif
    call RemoveItem(DropItemById( fromwhich, itemid))
endfunction

function ForceAutoAdd takes unit forwhich, boolean flag returns nothing
    local data dat = LoadInteger(h,GetHandleId(forwhich),1)
    if dat == 0 then
        return
    endif
    set dat.auto = flag
endfunction

private function autopick takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local data dat = LoadInteger(h,GetHandleId(u),1)
    local item ite = GetManipulatedItem() 
        if GetItemTypeId(ite) != inventitem and IsItemRegistered(GetItemTypeId(ite)) then
            call AddItem(ite, dat)
        endif
    set u = null
    set ite = null
endfunction

private function check takes nothing returns boolean
    local data dat = LoadInteger(h,GetHandleId(GetTriggerUnit()),1)
    return dat.auto == true
endfunction

private function LEFTpress takes nothing returns nothing
    local integer i = GetPlayerId(GetTriggerPlayer())
    set x[i] = x[i] - 1
    if x[i] == 0 then
        set x[i] = 3
    elseif x[i] == 2 then
        set x[i] = 1
        if y[i] > classes+1 then
            set y[i] = classes+1
        endif
    endif
    call UpdateDescription(i)
endfunction

private function UPpress takes nothing returns nothing
    local integer i = GetPlayerId(GetTriggerPlayer())
    set y[i] = y[i] - 1
    if y[i] == 1 then
        if x[i] == 3 then
            set y[i] = 28
        else
            set y[i] = classes+1
        endif
    endif
    call UpdateDescription(i)
endfunction

private function DOWNpress takes nothing returns nothing
    local integer i = GetPlayerId(GetTriggerPlayer())
    set y[i] = y[i] + 1
    if x[i] == 3 then
    if y[i] == 29 then
        set y[i] = 2
    endif
    else
    if y[i] == classes+2 then
        set y[i] = 2
    endif
    endif
    call UpdateDescription(i)
endfunction

private function RIGHTpress takes nothing returns nothing
    local integer i = GetPlayerId(GetTriggerPlayer())
    set x[i] = x[i] + 1
    if x[i] == 4 then
        set x[i] = 1
        if y[i] > classes+1 then
            set y[i] = classes+1
        endif
    elseif x[i] == 2 then
        set x[i] = 3
    endif
    call UpdateDescription(i)
endfunction

//! textmacro KEY takes KEY
set ttt = CreateTrigger()
call TriggerRegisterPlayerKeyEventBJ( ttt, Player(i), bj_KEYEVENTTYPE_DEPRESS, bj_KEYEVENTKEY_$KEY$ )
call TriggerAddAction( ttt, function $KEY$press )
//! endtextmacro

private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    local trigger tt = CreateTrigger()
    local trigger ttt = CreateTrigger()
    local integer i = 0
    
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddAction(t, function abilities)
    
    call TriggerRegisterTimerEvent(tt,0.01,true)
    call TriggerAddAction(tt, function AddingItemsAndMultiboardStuff)
    
    call TriggerRegisterAnyUnitEventBJ( ttt, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddAction(ttt, function autopick)
    call TriggerAddCondition(ttt, Condition(function check))
    
    loop
        exitwhen i == 12
        //! runtextmacro KEY("LEFT")
        //! runtextmacro KEY("RIGHT")
        //! runtextmacro KEY("UP")
        //! runtextmacro KEY("DOWN")
        set x[i] = 3
        set y[i] = 2
        set i = i + 1
    endloop
    
    call InitItems()
    call InitEquipment()
endfunction

endlibrary

Keywords:
multiboard, equipment, inventory, system, item, mui, mpi, vjass, campaign, rpg, orpg, hastable
Contents

Multiboard Inventory System (Map)

Reviews
18:54, 4th Oct 2009 TriggerHappy187: You fixed the O(n) searches, approved.

Moderator

M

Moderator

18:54, 4th Oct 2009
TriggerHappy187:

You fixed the O(n) searches, approved.
 
Level 4
Joined
Jul 1, 2009
Messages
65
seems really good i will test and rep when i get home......either way very good concept so far
 
Level 10
Joined
Aug 19, 2008
Messages
491
Shouldn't this be in the Jass section?
This is clearly not a spell, though it's a well done system. With some personal tweaks I'd really use this in my rpg. That is, if I had a rpg.
:sad:

--

Technically it's automatically MPI if it's MUI, so there's no need to write MPI aswell (though it is correct)
 
Level 16
Joined
Oct 12, 2008
Messages
1,570
No this should not be in the Jass section, as in Jass section, systems that are used for other utilities are posted.
Actually i am too lazy to open WE and check the code, but as you havent posted the code here (HINT! HINT! HINT!) and i already posted, i will do so. Wait for the edit..

OK, i havent looked through the code that much, but it seems ok.
I couldnt test it, probably due to 1.24 in-compatability.
Though the code seems ok, it is kinda annoying. Your coding style is sloppy and unreadable.
The first part misses alot of tabs, which makes it totally unreadable. Though the second part you use them again.
I will not say anything about its preformances,,
tips:
1) Improve code readability.
2) Make a 1.24-compatible (version).
 
Level 6
Joined
Jul 8, 2008
Messages
150
Looks cool but I think "Help" and "Info" should both be on the far left side (with "Info" still underneath "Help", of course).

Also, the "Equipment" text should look more something like this: (ignore the ''/'')
///////Head: null
/////Amulet: null
//////Chest: Cursed Armor
//////Hands: [null]
//Left Hand: Big Sword
/Right Hand: Big Shield
////////Feet: [null]
///////Extra: Special Box
Also, it would be great if you let users customize the equipment system (maybe they want toggle on/off, more extra items, rings, etc.).

Instead of highlighting the name of the selected item in green, you should have ">" in front of the selected item. Not only would it look better, but users might have color-coded items.

I won't; be using this system, but looks cool. :thumbs_up:
 
Level 2
Joined
Aug 3, 2009
Messages
14
I want to use this in my map since it is a very good system, But idk how to copy it exactly.
are there programs required or anything because i tryed copying the abilities and the triggers but this gave me compiling errors. Could you help?
 
Level 9
Joined
Oct 7, 2008
Messages
299
I want to use this in my map since it is a very good system, But idk how to copy it exactly.
are there programs required or anything because i tryed copying the abilities and the triggers but this gave me compiling errors. Could you help?
This was said million times in other threads... :hohum:
But I will repeat it one time for you :grin:
You need the JNGP [JassNewGenPack], its a pack of tools for better and more efficent JASSing, without it you could not save your map, if you imported this system.
You can download it here:
:fp: http://www.wc3c.net/showthread.php?t=90999
Here you are ... :3
 
Level 2
Joined
Aug 3, 2009
Messages
14
the jass helper always says... looking errors. i lfet for one hour and still didnt do anything... and then mess' the editor.
 

WBL

WBL

Level 2
Joined
Aug 12, 2009
Messages
4
Hello

This is a very nice system. However, I found a little bug, it uses a lot of skill slots, so, when a player learns skills and there are no more empty slots for the inventory system, the player can no longer use the system. Maybe make the inventory key event triggers rather than ability triggered.

A suggestion, it would be cool if "esc" was to close and/or open the inventory, just a thought. Have a good day.
 
Level 2
Joined
Aug 3, 2009
Messages
14
Yup got it all fixed just im getting some errors with the system ive download and implimented within my map.


call MultiboardSetItemValueBJ <--errors throughtout the whole thing if i fix this all errors probably fixed.

MultiboardSetItemStyleBJ
MultiboardSetItemIconBJ
MultiboardSetItemValueBJ
TriggerRegisterAnyUnitEventBJ
TriggerRegisterPlayerKeyEventBJ

Thos are the errors in the system highlighted in RED.
 
How do i make it so that the items are always on auto add, and i can remove the autoadd ability?
Also, the icons dont disapear when you close the multiboard

Great system btw

thx^^

UPDATE v.4.0
icons are disappearing correctly
and now you can enable/disable autoadd via ForceAutoAdd
by manipulating a new global variable you can hide the autoadd ability
 
After I save the test map (without changing anything ( i have a reflex in saving maps... ) ) and re-test it, all the icons show green in the multiboard.
What can cause this?
(to the new version)

hmm don't know...

i tried it with a copy of it and everything works fine...

maybe you havent JNGP 5d or your copy is corrupted...
 
Very nice system, reminds me of Dark Invasion II's sort of.

  • I think you should make a separate trigger to init the items. Your current trigger is really long and it would just make it more jumbled if someone registered lots of items.
  • Your doing a lot of O(n) searches, use some sort of item indexing system to increase efficiency. You can also use hashtables which would be a far better choice than looping through items.
  • In your AddingItemsAndMultiboardStuff function you don't need to set u = null since it will already be null by the end of the FirstOfGroup loop.
  • Your also dynamically creating groups in that function, simple re-use a global like your doing with the other group.
  • Also why use GroupAddGroup(g,d), it can easily be changed to the native equivalent.

Once you make those improvements I will likely have other suggestions for your coding, lets take it one step at a time.
 
Level 14
Joined
Nov 18, 2007
Messages
816
I took a look at this, since someone asked me for help to combine this with some save system.

I dont know where to start. Its a monstrosity assembled without thought.
How to add an item to the inventory? HOW TO DO ANYTHING WITH THIS? Theres no API, and whats there is hardly useful at all.
The codes hard to follow, lacks comments, proper indentation and good design.
You couldve used Table, btw.

Seriously, how did this get approved?
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
Nice sys

Nice system but im getting a glitch. When i go to open inventory, the multiboard appears, but its empty + the size of my fingernail (0 rows, 0 columns, no names or data whatsoever)
 
Level 3
Joined
Feb 12, 2011
Messages
38
Hi The Witcher,
I really like this inventory system (5/5) and even plan to import it into my map.
But I got following problems:
1. I do not understand where you took the item id from (I looked at the items but couldn't find the id)
2. I made a AoS-type of map. therefore I have no ability buttons left (It's full with 5 abilities+recall) So does it also work without abilities by only pressing a key (for example o) ? -I'm new to jass (actually I started learning it yesterday so I still do not understand the greater part of it)
3. when I only import the config trigger (the one I am supposed to) my map won't open in Warcraft although your test-map does.

Some of my points might seem apparent but as I said: I'm new to jass and still do not understand most of it. Therefore I hope you understand my issues.
I hope someone can answer my questions,
Thanks in advance,
acabar100

And I forgot: If I get this working, I'll also give you +rep for it.
-solved-except for #2-
 
Last edited:
Level 2
Joined
Jun 19, 2016
Messages
16
No, don't add esc as a open/close inventory. But I wonder something, I get it to work on one of my maps, but on the one i really want it on, It just shows a little box up in the right corner instead of the whole inventory system (ingame).
 
Level 5
Joined
Feb 13, 2019
Messages
128
Would anyone here know offhand how to make it so if a unit dies it will drop the equipped items as if they were in it's regular WC3 inventory? :peasant-confused::peasant-confused:

Pretty please? :3
 
Level 2
Joined
Jun 19, 2016
Messages
16
U add inventory ability on that unit and give unit that item in the start og the map via trigger. Then make unit drop item on death via trigger.
 
Top