O problema ocorre porque você remove os itens enquanto ainda está iterando o container. Em servidores OT (especialmente base TFS 0.x / 8.60), quando você remove um item de um container, os índices mudam. Então o loop pula itens e você precisa clicar novamente.
Por que acontece
Exemplo:
Container:
slot 0: gold
slot 1: sword
slot 2: shieldLoop:
pega slot 0 → remove gold
container vira:
slot 0: sword
slot 1: shieldloop vai para i = 2 → shield
➡️ sword foi pulada
Por isso você precisa clicar várias vezes.
Solução correta
Sempre remova do último slot para o primeiro.
Assim os índices não mudam para os itens que ainda não foram processados.
Script corrigido
function onUse(cid, item, fromPosition, itemEx, toPosition)
if getItemAttribute(item.uid, "corpseowner") ~= getPlayerGUID(cid) then
return doPlayerSendCancel(cid, "Esse corpo foi morto por outro jogador")
end
local items = {}
local size = getContainerSize(item.uid)
-- percorre de trás para frente
for i = size - 1, 0, -1 do
local it = getContainerItem(item.uid, i)
if it.uid > 0 then
table.insert(items, {it.itemid, it.type})
doRemoveItem(it.uid)
end
end
if #items > 0 then
for k = 1, #items do
local playerItem = getPlayerItemById(cid, true, items[k][1])
if playerItem.uid > 0 then
local totalType = playerItem.type + items[k][2]
if totalType > 100 then
doPlayerAddItem(cid, items[k][1], totalType - 100)
doTransformItem(playerItem.uid, items[k][1], 100)
else
doTransformItem(playerItem.uid, items[k][1], totalType)
end
else
doPlayerAddItem(cid, items[k][1], items[k][2])
end
end
end
return true
endMelhorias recomendadas (muito importantes)
Para OTServer 8.60 eu recomendo também:
1️⃣ evitar limite manual de stack
O servidor já controla stack automaticamente.
Você pode simplificar MUITO:
doPlayerAddItem(cid, items[k][1], items[k][2])Sem precisar de:
getPlayerItemById
doTransformItem
limite 100
2️⃣ Versão muito mais limpa
Esta versão já funciona como quick loot real:
function onUse(cid, item, fromPosition, itemEx, toPosition)
if getItemAttribute(item.uid, "corpseowner") ~= getPlayerGUID(cid) then
return doPlayerSendCancel(cid, "Esse corpo foi morto por outro jogador")
end
local size = getContainerSize(item.uid)
for i = size - 1, 0, -1 do
local it = getContainerItem(item.uid, i)
if it.uid > 0 then
doPlayerAddItem(cid, it.itemid, it.type)
doRemoveItem(it.uid)
end
end
return true
endResultado
✔ Clicou no corpo 1 vez
✔ Todos os itens vão para a bag
✔ Nenhum item é pulado
✔ Código muito mais simples
Fonte: ChatGPT
Por
Pissolato, · Postado