Page 1 of 1

Destroying inventory items

Posted: Thu Feb 13, 2014 9:13 pm
by AdrTru
I write script for destroying object from inventory.

Script scaned inventory and make table with item information.
After this, is working with this table. Its possible to scan this table for another informations.



InvTable definition
SpoilerShow
InvTable = {["player"]=player, -- "ordinal of champion" or "ordinal of champion"+*+"slot for container"(if item is in)
["container"]=container.id, -- id of container or ""
["slot"]=s, -- slot where is item in container/character
["name"]=item.name,
["id"]=item.id,
["count"]=count, -- count of item ( stack size or 1)
["contained"]=contained} -- count of items ( if this object is container)
There are 3 main functions
TestInventory({1,"mortar",2,"flask"}) -- test if inventory contains items by table definitions (e.g. {1,"mortar",2,"flask"} )
DeleteInventory({2,"potion_healing",1,"potion_energy"}) -- remove defined items from directory (containers will be removed with all contained items )
DeleteInventoryExcept({"flask","scroll"}) -- will be removed all items except this defined

Code: Select all

function check()
  if TestInventory({1,"mortar",2,"flask"}) then print("OK") else print("Sp") end
end

function delete()
  if DeleteInventory({2,"potion_healing",1,"potion_energy"}) then print("OK") else print("Sp") end
end

function deleteEx()
  if DeleteInventoryExcept({"flask","scroll"}) then print("OK") else print("Sp") end
end


------------------------------------ if tt definition is exactly in inventory ----------------------------------
function TestInventory(tt)
local i,j,d
local ttab = {}
  InvTable = getInvTable()
  for i = 1, #InvTable do
    for j = 2, #tt, 2 do
      if (InvTable[i].name == tt[j])and(tt[j-1]>0) then
        d = math.min(InvTable[i].count, tt[j-1])
        tt[j-1]=tt[j-1]-d
        table.insert(ttab,InvTable[i])
        ttab[#ttab].count = d
      end
    end
  end
  for j = 1, #tt-1, 2 do
    if tt[j]>0 then return false,{} end
  end
  return true, ttab
end

--------------------------------- delete tt defintion items from inventory ---------------------------------
function DeleteInventory(tt)
local i
local e,tab = TestInventory(tt)
  if e then
    for i = #tab,1,-1 do
      if tab[i].contained==0 then
        DeleteItem(tab[i])
        table.remove(tab,i)
      end
    end
    if #tab == 0 then return true end
    for i = #tab,1,-1 do
      RemoveContained(tab[i])
      DeleteItem(tab[i])
      table.remove(tab,i)
    end
  else 
    return false
  end
  return true
end

----------------------------------- delete all items from inventory except tt(table of names) ---------------
function DeleteInventoryExcept(tt)
local tab = getInvTable()
local i
  for i = #tab,1,-1 do
    if IsStringIn(tt,tab[i].name)==true then
      table.remove(tab,i)
    end
  end
  for i = #tab,1,-1 do
    if tab[i].contained==0 then
      DeleteItem(tab[i])
      table.remove(tab,i)
    end
  end
  if #tab == 0 then return true end
  for i = #tab,1,-1 do
    RemoveContained(tab[i])
    DeleteItem(tab[i])
    table.remove(tab,i)
  end
end











---- Utility functions ---------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------- delete item from player/container ------------------------------------
function DeleteItem(item)
--print("del>"..item.container.."/"..item.slot.."/"..item.name)
local container,it
local tc = split(item.player,"*")
  container = party:getChampion(tc[1]*1)
  repeat
    table.remove(tc,1)
    if #tc>0 then
      container = container:getItem(tc[1]*1)
    end
  until (#tc < 2)
  if container ~= nil then
--    print("remove>"..item.container.."/"..item.slot.."/"..item.name)
    it = container:getItem(item.slot)
    if it:getStackSize() > item.count then
      it:setStackSize(it:getStackSize()-item.count)
    else
      container:removeItem(item.slot)
    end
  end
end

---------------------------------------- remove all items from container -----------------------------------------
function RemoveContained(item)
local i,c,it,itid
local tc = split(item.player,"*")
  container = party:getChampion(tc[1]*1)
  if container ~= nil then
    repeat
      table.remove(tc,1)
      if #tc>0 then
        container = container:getItem(tc[1]*1)
      end
    until (#tc < 2)
  end
  if container ~= nil then
    c = 0
    for i in container:containedItems() do
      c = c + 1
    end
    i = 1
    print(c)
    while (c > 0) do
--      print(">"..i)
      it = container:getItem(i)
      if it ~= nil then
        container:removeItem(i)
        c = c - 1
      end
      i = i + 1
    end
  end
end

-------------------------------------- print all items from table --------------------------------------------------
function printInventory()
  InvTable = getInvTable()
  for k,v in pairs(InvTable) do
    print(v.player.."/"..v.container.."/"..v.slot.."/"..v.name.."/"..v.id.."/"..v.count.."/"..v.contained)
  end
end

-------------------------------------- get table with all items where players have --------------------------------
function getInvTable()
local thisPlayer,itemSlot,currItem,Champion,contained,count
local tab = {}
  for thisPlayer=1,4 do
    Champion = party:getChampion(thisPlayer)
    for itemSlot=1,31 do
      if Champion:getItem(itemSlot) ~= nil then 
        currItem = Champion:getItem(itemSlot)
        contained = TestContainer(currItem)
        count = currItem:getStackSize()
        if count == 0 then count=1 end
        table.insert(tab,{["player"]=thisPlayer,["container"]="",
                          ["slot"]=itemSlot,["name"]=currItem.name,
                          ["id"]=currItem.id,["count"]=count,
                          ["contained"]=contained})
        if contained > 0 then 
          tab = ContainedItems(tab,thisPlayer.."*"..itemSlot,currItem,contained)
        end
      end 
    end
  end
return tab
end

------------------------------------ add table of contained items ------------------------------------------------
function ContainedItems(tab,player,container,c)
local s = 0
local item,contained,count
  repeat
    item = container:getItem(s)
    if item ~= nil then
      c = c - 1
      contained = TestContainer(item)
      count = item:getStackSize()
      if count == 0 then count=1 end
      table.insert(tab,{["player"]=player,["container"]=container.id,
                        ["slot"]=s,["name"]=item.name,
                        ["id"]=item.id,["count"]=count,
                        ["contained"]=contained})
      if contained > 0 then 
        tab = ContainedItems(tab,player.."*"..s,item,contained)
      end
    end
    s = s + 1
  until c==0
  return tab
end

------------------------------------- test for item have some conained -------------------------------------
function TestContainer(container)
local count = 0
local i
  for i in container:containedItems() do 
    count = count + 1
  end
return count
end

------------------------------------- test for name is in table --------------------------------------------
function IsStringIn(tab,name)
  for i = 1,#tab do
    if tab[i]==name then return true end
  end
  return false
end

------------------------------------ split string ----------------------------------------------------------
function split(inputstr, sep)
        if sep == nil then
                sep = "%s"
        end
        t={} ; i=1
        for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
                t[i] = str
                i = i + 1
        end
        return t
end

Re: Destroying inventory items

Posted: Sat Feb 15, 2014 10:31 am
by Eleven Warrior
Now this is awesome coding AdrTru brilliant ...:)

Re: Destroying inventory items

Posted: Sun Feb 16, 2014 6:46 am
by Diarmuid
This looks good, although we already have grimq which provides these capabilities and much more: viewtopic.php?f=14&t=4256&hilit=grimq

Re: Destroying inventory items

Posted: Sun Feb 16, 2014 10:49 am
by AdrTru
You are right, Diarmuid.
I hesitate to publish scripts cooperating with anotehr frameworks. Becouse there there is more difficult intalation.
But in this situation it would be better.