Its not an good idea to save items by userdata, you cant reconstruct items and if any of these items are deleted you will face a nice null pointer crash, I dont recommend any manipulation with items like you suggest.Another workaround which isn't as weird as label targeting backpacks, is to add standard rules to backpacks of varying colors. Lets say yellow backpack represents currency. If you have enabled the system (with etc a talkaction), any gold looted will automatically be placed wherever you have stored that yellow backpack in your inventory.
This could be extended to a system where you configure rules toward backpacks of varying colors. The same basic principle follows as my previous sample, where you on login scan through inventory, initialize various containers based on backpack colors to place loot items in.
Its not an good idea to save items by userdata, you cant reconstruct items and if any of these items are deleted you will face a nice null pointer crash, I dont recommend any manipulation with items like you suggest.
It will never work, you can try it yourself.Which is why we need to add unique item references to the game
[suggestion] Unique item reference database structure
Check link for suggested schema changes: https://gist.github.com/Znote/2508c1d50fcca318f80b3ea4bc6f10a3 CREATE TABLE IF NOT EXISTS `items` ( `item_uid` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `itemtype` smallint(6) NOT NULL, `count` smallint(5) NOT NULL, `attributes` blob NOT NULL...otland.net
I think we can still grab the uid from the userdata onlogin, and from that uid attempt to re-create the userdata whenever needed, without fear of null pointer?
You still need to iterate recursively each time you need to find backpack, but yeah you could.Item custom attributes by Mkalo · Pull Request #1997 · otland/forgottenserver
Introducing 3 new methods to Item class to Lua API: item:setCustomAttribute(key, value) item:getCustomAttribute(key) item:removeCustomAttribute(key) Key types: string or number Value types: string,...github.com
Couldn't you use this to stamp the item?
local function scanContainer(cid, position)
local player = Player(cid)
if not player then
return
end
local corpse = Tile(position):getTopDownItem()
if not corpse or not corpse:isContainer() then
return
end
if corpse:getType():isCorpse() and corpse:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == cid then
for a = corpse:getSize() - 1, 0, -1 do
local containerItem = corpse:getItem(a)
if containerItem then
for b = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do
if player:getStorageValue(b) == containerItem:getId() then
containerItem:moveTo(player)
end
end
if player then
if isItemStackable(containerItem:getId()) then
local g = containerItem:getCount()
local g2 = containerItem:getCount() * 1.1 / 10
local g3 = containerItem:getCount()
local g4 = (containerItem:getCount() * 100) * 1.1 / 10
local g5 = containerItem:getCount()
local g6 = (containerItem:getCount() * 1000) * 1.1 / 10
if containerItem:getId() == 2148 then
containerItem:remove()
doPlayerSetBalance(player, getPlayerBalance(player) + (containerItem:getCount() * 1.1))
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Gold Coins: "..g.." (+"..g2..") - !bank balance.")
end
if containerItem:getId() == 2152 then
containerItem:remove()
doPlayerSetBalance(player, getPlayerBalance(player) + ((containerItem:getCount() * 100) * 1.1))
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Platinum Coins: "..g3.." (+"..g4.."Gold Coin) - !bank balance.")
end
if containerItem:getId() == 2160 then
containerItem:remove()
doPlayerSetBalance(player, getPlayerBalance(player) + ((containerItem:getCount() * 1000) * 1.1))
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Crystal Coins: "..g5.." (+"..g6.."Gold Coin) - !bank balance.")
end
end
end
if not player then
if isItemStackable(containerItem:getId()) then
if containerItem:getId() == 2148 then
containerItem:remove()
doPlayerSetBalance(player, getPlayerBalance(player) + containerItem:getCount())
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Gold Coins: "..g.." (+0) - !bank balance.")
end
if containerItem:getId() == 2152 then
containerItem:remove()
doPlayerSetBalance(player, getPlayerBalance(player) + (containerItem:getCount() * 100))
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Platinum Coins: "..g3.." (+0) - !bank balance.")
end
if containerItem:getId() == 2160 then
containerItem:remove()
doPlayerSetBalance(player, getPlayerBalance(player) + (containerItem:getCount() * 1000))
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Crystal Coins: "..g5.." (+0) - !bank balance.")
end
end
end
end
end
end
end
function onKill(player, target)
if not target:isMonster() then
return true
end
addEvent(scanContainer, 100, player:getId(), target:getPosition())
return true
end
function onSay(player, words, param)
local split = param:split(",")
local action, split2 = split[1], split[2]
if action == "add" then
if not split2 then
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Please enter the itemID or name.\n!autoloot add, itemId or !autoloot add, itemName.")
return false
end
local item = split2:gsub("%s+", "", 1)
local itemType = ItemType(item)
if itemType:getId() == 0 then
itemType = ItemType(tonumber(item))
if itemType:getId() == 0 then
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "There is no item with that id or name.")
return false
end
end
local itemName = tonumber(split2) and itemType:getName() or item
local size = 0
for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do
local storage = player:getStorageValue(i)
if size == AUTO_LOOT_MAX_ITEMS then
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "The list is full, please remove from the list to make some room.")
break
end
if storage == itemType:getId() then
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, itemName .." is already in the list.")
break
end
if storage <= 0 then
player:setStorageValue(i, itemType:getId())
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, itemName .." has been added to the list.")
break
end
size = size + 1
end
elseif action == "remove" then
if not split2 then
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Please enter the itemID or name.\n!autoloot remove, itemId or !autoloot remove, itemName.")
return false
end
local item = split2:gsub("%s+", "", 1)
local itemType = ItemType(item)
if itemType:getId() == 0 then
itemType = ItemType(tonumber(item))
if itemType:getId() == 0 then
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "There is no item with that id or name.")
return false
end
end
local itemName = tonumber(split2) and itemType:getName() or item
for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do
if player:getStorageValue(i) == itemType:getId() then
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, itemName .." has been removed from the list.")
player:setStorageValue(i, 0)
return false
end
end
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, itemName .." was not founded in the list.")
elseif action == "show" then
local text = "-- Auto Loot List --\n"
local count = 1
for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do
local storage = player:getStorageValue(i)
if storage > 0 then
text = string.format("%s%d. %s\n", text, count, ItemType(storage):getName())
count = count + 1
end
end
if text == "" then
text = "Empty"
end
player:showTextDialog(1950, text, false)
elseif action == "clear" then
for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do
player:setStorageValue(i, 0)
end
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "The autoloot list has been cleared.")
else
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Use the commands: !autoloot {add, remove, show, clear}")
end
return false
end
Hey i got problem with autoloot when i want add any item to slot, help
Lua:function onSay(player, words, param) local split = param:split(",") local action, split2 = split[1], split[2] if action == "add" then if not split2 then player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Please enter the itemID or name.\n!autoloot add, itemId or !autoloot add, itemName.") return false end local item = split2:gsub("%s+", "", 1) local itemType = ItemType(item) if itemType:getId() == 0 then itemType = ItemType(tonumber(item)) if itemType:getId() == 0 then player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "There is no item with that id or name.") return false end end local itemName = tonumber(split2) and itemType:getName() or item local size = 0 for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do local storage = player:getStorageValue(i) if size == AUTO_LOOT_MAX_ITEMS then player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "The list is full, please remove from the list to make some room.") break end if storage == itemType:getId() then player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, itemName .." is already in the list.") break end if storage <= 0 then player:setStorageValue(i, itemType:getId()) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, itemName .." has been added to the list.") break end size = size + 1 end elseif action == "remove" then if not split2 then player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Please enter the itemID or name.\n!autoloot remove, itemId or !autoloot remove, itemName.") return false end local item = split2:gsub("%s+", "", 1) local itemType = ItemType(item) if itemType:getId() == 0 then itemType = ItemType(tonumber(item)) if itemType:getId() == 0 then player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "There is no item with that id or name.") return false end end local itemName = tonumber(split2) and itemType:getName() or item for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do if player:getStorageValue(i) == itemType:getId() then player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, itemName .." has been removed from the list.") player:setStorageValue(i, 0) return false end end player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, itemName .." was not founded in the list.") elseif action == "show" then local text = "-- Auto Loot List --\n" local count = 1 for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do local storage = player:getStorageValue(i) if storage > 0 then text = string.format("%s%d. %s\n", text, count, ItemType(storage):getName()) count = count + 1 end end if text == "" then text = "Empty" end player:showTextDialog(1950, text, false) elseif action == "clear" then for i = AUTOLOOT_STORAGE_START, AUTOLOOT_STORAGE_END do player:setStorageValue(i, 0) end player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "The autoloot list has been cleared.") else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Use the commands: !autoloot {add, remove, show, clear}") end return false end
-- AutoLoot config
AUTO_LOOT_MAX_ITEMS = 5
-- Reserved storage
AUTOLOOT_STORAGE_START = 10000
AUTOLOOT_STORAGE_END = AUTOLOOT_STORAGE_START + AUTO_LOOT_MAX_ITEMS
-- AutoLoot config end
Need add variables in data/global.lua, paste this:
Lua:-- AutoLoot config AUTO_LOOT_MAX_ITEMS = 5 -- Reserved storage AUTOLOOT_STORAGE_START = 10000 AUTOLOOT_STORAGE_END = AUTOLOOT_STORAGE_START + AUTO_LOOT_MAX_ITEMS -- AutoLoot config end
my advice for you is to read again the first post as it explains exactly what/where you need to change in order for this script to work!Thanks for info, no errors but now looting from corpses wont work, or example from troll, any ideas?
@Also new error