Lua This free inventory check script won't work.

Discussion in 'Support' started by Demnish, Sep 14, 2018.

  1. Demnish

    Demnish Tibian Hero

    Joined:
    Sep 28, 2011
    Messages:
    248
    Likes Received:
    12
    Best Answers:
    1
    I need a check to determine if the player has any available slots where items can be placed.
    This script will be used for quests etc, I've already made a check on the player's cap, now I need to check for the player's available slots.
    Code (Text):
    1. function onUse(cid, item, frompos, item2, topos)
    2.     local BP = getPlayerSlotItem(cid, CONST_SLOT_BACKPACK).uid
    3.     if getContainerCapByID(BP) < 1 then
    4.         doStuff
    5.     else
    6.         doOtherStuff
    7.     end
    Can't get it to work, all I get is:
    With or without a backpack.

    This is the function from functions.lua:
    Code (Text):
    1. getContainerCapById(itemid)
    Any help will be greatly appreciated! :)
     
    Last edited: Sep 14, 2018
  2. gudan garam

    gudan garam Active Member

    Joined:
    Feb 13, 2011
    Messages:
    238
    Likes Received:
    60
    Best Answers:
    8
    Which tfs version are you running?

    I think getContainerCapByID expects you to pass the items id, depending on the tfs version you are running the BP variable could be userdata or whatever it was in the earlier versions.

    Maybe try
    Code (Text):
    1. getContainerCapByID(BP.itemid)
    2. or
    3. getContainerCapByID(BP:getId())
    or something like that.

    Remember to always post the tfs version you are using, it is really helpful.
     
  3. Demnish

    Demnish Tibian Hero

    Joined:
    Sep 28, 2011
    Messages:
    248
    Likes Received:
    12
    Best Answers:
    1
    I'm not running TFS, I'm actually running OTServ 0.6.4 since I read it is the most stable distro.
    I tried the ones you mentioned and while it didn't work. I got a new error which was quite interesting:
    (I also tried "getContainerCapByID(BP.uid)" and got the same result)

    This works as far as checking for backpack, however checking for remaining slots does not:
    Code (Text):
    1.  
    2. function onUse(cid, item, frompos, item2, topos)'
    3.     local BP = getPlayerSlotItem(cid, CONST_SLOT_BACKPACK)
    4.     if BP.uid == 0 or getContainerCap(BP.uid) == false then
    5.         doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You have no backpack.")
    6.     elseif getContainerCap(BP.uid) >= 1 then
    7.         doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Item added!")
    8.     else
    9.         doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You have no room.")
    10.     end
    11.  
     
    Last edited: Sep 14, 2018
  4. Xikini

    Xikini I whore myself out for likes

    Joined:
    Nov 17, 2010
    Messages:
    3,685
    Likes Received:
    1,901
    Best Answers:
    93
    I believe you are trying to use a cube in place of a triangle.

    Try something like this instead.
    Code (Lua):
    1. local item_id, count = 1988, 1
    2.  
    3. function onUse(cid, item, fromPosition, itemEx, toPosition)
    4.     local reward, weight = doCreateItemEx(item_id, count), getItemWeightById(item_id, count)
    5.     if doPlayerAddItemEx(cid, reward, false) == RETURNVALUE_NOERROR then
    6.         doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You have found a " .. getItemNameById(item_id) .. " weighing ".. string.format("%.2f", weight) .." oz.")
    7.         return true
    8.     else
    9.         local cap = getPlayerFreeCap(cid)
    10.         if cap < weight then
    11.             doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Require " .. string.format("%.2f", weight - cap) .. " more capacity to receive this reward weighing ".. string.format("%.2f", weight) .." oz.")
    12.         else
    13.             doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You don't have any room to obtain this reward.")
    14.         end
    15.     end
    16.     return true
    17. end
    -- Edit
    If you are getting errors with 'weight' check below.

    -- in case your lib doesn't have the function for whatever reason, put this into data/lib/050-function.lua
    Code (Lua):
    1. function getItemWeightById(itemid, count, precision)
    2.     local item, count, precision = getItemInfo(itemid), count or 1, precision or false
    3.     if(not item) then
    4.         return false
    5.     end
    6.    
    7.     if(count > 100) then
    8.         -- print a warning, as its impossible to have more than 100 stackable items without "cheating" the count
    9.         --print('[Warning] getItemWeightById', 'Calculating weight for more than 100 items!')
    10.     end
    11.    
    12.     local weight = item.weight * count
    13.     return precission and weight or math.round(weight, 2)
    14. end
     
    Demnish likes this.
  5. Demnish

    Demnish Tibian Hero

    Joined:
    Sep 28, 2011
    Messages:
    248
    Likes Received:
    12
    Best Answers:
    1
    I think it's easier if I just post my whole script:
    Code (Text):
    1. local ITEM = 2195
    2. local COUNT = 1
    3. local DROPONGROUND = false
    4.  
    5. local ITEMNAME = getItemName(ITEM)
    6. local STORAGE = getItemIdByName(ITEMNAME)
    7. local WEIGHT = getItemWeightById(ITEM, COUNT)
    8.  
    9. function onUse(cid, item, frompos, item2, topos)
    10.     if getPlayerFreeCap(cid) >= WEIGHT then
    11.         if getPlayerStorageValue(cid, STORAGE) ~= 1 then
    12.             if COUNT == 1 then
    13.                 doPlayerAddItem(cid, ITEM, COUNT, DROPONGROUND)
    14.                 doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You have found "..ITEMNAME.."!")
    15.                 doSendMagicEffect(getCreaturePosition(cid), CONST_ME_MAGIC_GREEN)
    16.                 setPlayerStorageValue(cid, STORAGE, 1)
    17.             elseif COUNT > 1 then
    18.                 doPlayerAddItem(cid, ITEM, COUNT, DROPONGROUND)
    19.                 doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You have found "..COUNT.."x "..ITEMNAME.."!")
    20.                 doSendMagicEffect(getCreaturePosition(cid), CONST_ME_MAGIC_GREEN)
    21.                 setPlayerStorageValue(cid, STORAGE, 1)
    22.             end
    23.         else
    24.             doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "It is empty.")
    25.             doSendMagicEffect(getCreaturePosition(cid), CONST_ME_POFF)
    26.         end
    27.     else
    28.         doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You do not have enough capacity.")
    29.     end
    30. end
    31.  
    I've solved the cap check, more or less. But what I haven't solved is the check to see if the player has any free inventory.
    Since my script runs on "DROPONGROUND = false" the player will recieve the reward even if he lacks the inventory slot but has the capacity, which triggers the storage and the item can never again be claimed.
    I managed to make a temporary fix like they used back in the old OT's by making DROPONGROUND = true, which in turn just drops the item on the ground, but then again other players can pick it up instead, which makes it just a temporary solution to a permanent problem.
     
    Last edited: Sep 14, 2018
  6. Xikini

    Xikini I whore myself out for likes

    Joined:
    Nov 17, 2010
    Messages:
    3,685
    Likes Received:
    1,901
    Best Answers:
    93
    I posted exactly what you wanted 3 hours before you posted this reply.
    Here's the exact same script.. but with your '1 time use storage' requirement.
    Code (Lua):
    1. local item_id, count = 1988, 1
    2. local storage = 45001
    3.  
    4. function onUse(cid, item, fromPosition, itemEx, toPosition)
    5.     if getPlayerStorageValue(cid, storage) == 1 then
    6.         doSendMagicEffect(fromPosition, CONST_ME_POFF)
    7.         doPlayerSendCancel(cid, "Chest is empty.")
    8.         return true
    9.     end
    10.    
    11.     local reward, weight = doCreateItemEx(item_id, count), getItemWeightById(item_id, count)
    12.     if doPlayerAddItemEx(cid, reward, false) == RETURNVALUE_NOERROR then
    13.         doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You have found a " .. getItemNameById(item_id) .. " weighing ".. string.format("%.2f", weight) .." oz.")
    14.         setPlayerStorageValue(cid, storage, 1)
    15.         return true
    16.     else
    17.         local cap = getPlayerFreeCap(cid)
    18.         if cap < weight then
    19.             doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Require " .. string.format("%.2f", weight - cap) .. " more capacity to receive this reward weighing ".. string.format("%.2f", weight) .." oz.")
    20.         else
    21.             doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You don't have any room to obtain this reward.")
    22.         end
    23.     end
    24.     return true
    25. end
     
    Demnish likes this.
  7. Demnish

    Demnish Tibian Hero

    Joined:
    Sep 28, 2011
    Messages:
    248
    Likes Received:
    12
    Best Answers:
    1
    Yeah, thanks a lot for helping me out mate, however I had to abandon that distro. Way too many bugs and glitches to be worth working on, I switched to a 10.98 distro instead since the nature of my project doesn't really depend on the client version. Also a newer distro might be more worth putting time into, the OTServ 0.6.4 had problems such as manas not usable on ladders and this problem I mentioned in this thread among a lot of other problems. Since my VC17 is problematic I really have no energy to work with the sources either so I chose TFS 1.2 instead since it seems to have what I'm looking for, more or less anyway.

    Keep helping the community, we appreciate you around here!
     
  8. cbrm

    cbrm Just another mod Staff Member Global Moderator

    Joined:
    Jan 6, 2009
    Messages:
    6,549
    Likes Received:
    849
    Best Answers:
    0
    Code (Lua):
    1. function _getContainerFreeSlots(container)
    2.     return getContainerCap(container) - getContainerSize(container)
    3. end
    4.  
    5. function getContainerFreeSlots(container)
    6.     if not isContainer(container) then
    7.         return 0
    8.     end
    9.  
    10.     local t, v = {}, 0
    11.     for i = 0, getContainerSize(container)-1 do
    12.         local item = getContainerItem(container, i)
    13.         if isContainer(item.uid) then
    14.             table.insert(t, item.uid)
    15.         end
    16.     end
    17.  
    18.     for _, check in pairs(t) do
    19.         v = v + _getContainerFreeSlots(check)
    20.     end
    21.  
    22.     return v + _getContainerFreeSlots(container)
    23. end
    usage
    Code (Lua):
    1. if (getContainerFreeSlots(getPlayerSlotItem(cid, CONST_SLOT_BACKPACK).uid) == 0) then
    2. -- has full bp!
     
    Danger II and Xikini like this.

Share This Page

Loading...