• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

[TFS 1.3] Small Autoloot

Well, now I got it by having to redo all over the server lol. But now, I get an error for attempt to index field 'storage' a nil value. I am using tfs 1.4 but still did the changes to the compat file for the player storages although also shows about monster.lua file for the ondroploot.

View attachment 69641
Also, this keeps sending to the console like if it's doing this check every time and doesn't even let me log out or anything and to logout I have to close the client directly
 
@Sarah Wesker i have same erro as @Fabi Marzan, i already merge the new lines from campact.luz, did just lines and try all file.. but same error, have any ideia?
im using: The Forgotten Server - Version 1.5 (Nekiro's 8.60 downgrade)
Post automatically merged:

IT WORKSS!!!
after all morning search the problem, i found it, just a catch, after look in "/data/lib/lib.lua" i see this:
dofile('data/lib/custom/compatCustom.lua')
and i spend all time editing the file "/data/lib/compact/compact.lua" ... daaaaammmm
after edit the right file, almost works, the final touch is change this lines in "small_autoloot.lua"
"player:showTextDialog(2160, ...." i change it to 1948(parchment) and voiala, IT WORKSSssssss
 

Attachments

Last edited:
Someone was able to fix this problem in 1.5
Downgrades nekiro? try using " A new way to manage player storages.."
no positive results


C++:
attempt to call method 'getAutoLootItem' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootItem'
        ...ta\scripts\eventcallbacks\monster\default_onDropLoot.lua:24: in function 'callback'
        ...mpilaciones\1.5\800\data\scripts/lib\event_callbacks.lua:131: in function 'EventCallback'
        data/events/scripts/monster.lua:3: in function <data/events/scripts/monster.lua:1>
 
for people who uses 860

change from all
Lua:
player:showTextDialog
If it has number 2160 change it to 1948

example:
Lua:
 player:showTextDialog(2160, table.concat(description, '\n'), false)
to
Lua:
player:showTextDialog(1948, table.concat(description, '\n'), false)
 
Hi @Sarah Wesker! I have a weird, nothing related to the system itself but if an item has a special description, such as happens with TFS-Upgrade-System/scripts/UpgradeSystem at master · Oen44/TFS-Upgrade-System (https://github.com/Oen44/TFS-Upgrade-System/tree/master/scripts/UpgradeSystem), the item will be autolooted without considering it. For example, I have settled up everything to loot every item as "unidentified", also items have "item level". But as soon I autoloot any item, it gets "item level" to 0, and gets its raw description back (no more unidentified). Is just an observation, guess it's going to help somehow. Regards!
 
Last edited:
how to remove bank version and make think only for premium players?
 
currencyToBank = false

what is "think"?
Wanted to say make it work only. I'm looking the script and it's even better so
Post automatically merged:

have no errors in console but nothing happens
except for this in otclientv8
Lua:
ERROR: ProtocolGame parse message exception (232 bytes, 213 unread, last opcode is 0x96 (150), prev opcode is 0xffffffff (-1)): InputMessage eof reached
Packet has been saved to packet.log, you can use it to find what was wrong. (Protocol: 860)
 
Last edited:
no errors in console
but in client i receive this
Lua:
ERROR: ProtocolGame parse message exception (233 bytes, 214 unread, last opcode is 0x96 (150), prev opcode is 0xffffffff (-1)): InputMessage eof reached
Packet has been saved to packet.log, you can use it to find what was wrong. (Protocol: 860)

Code:
ProtocolGame parse message exception (233 bytes, 214 unread, last opcode is 0x96 (150), prev opcode is 0xffffffff (-1), proto: 860): InputMessage eof reached
ec 00 59 6b 45 8f e1 00
96 02 00 00 00 e3 0b 01 d1 00 d1 00 45 78 61 6d 70 6c 65 73 20 6f 66 20 75 73 65 3a 0a 21 61 75 74 6f 6c 6f 6f 74 74 65 73 74 20 61 64 64 2c 67 6f 6c 64 20 63 6f 69 6e 0a 21 61 75 74 6f 6c 6f 6f 74 74 65 73 74 20 72 65 6d 6f 76 65 2c 67 6f 6c 64 20 63 6f 69 6e 0a 21 61 75 74 6f 6c 6f 6f 74 74 65 73 74 20 63 6c 65 61 72 0a 21 61 75 74 6f 6c 6f 6f 74 74 65 73 74 20 73 68 6f 77 0a 21 61 75 74 6f 6c 6f 6f 74 74 65 73 74 20 65 64 69 74 0a 0a 7e 41 76 61 69 6c 61 62 6c 65 20 73 6c 6f 74 73 7e 0a 66 72 65 65 41 63 63 6f 75 6e 74 3a 20 31 30 0a 70 72 65 6d 69 75 6d 41 63 63 6f 75 6e 74 3a 20 32 30 0a 63 75 72 72 65 6e 63 79 20 74 6f 20 62 61 6e 6b 3a 20 79 65 73 00 00 00 00
 
no errors in console
but in client i receive this
Lua:
ERROR: ProtocolGame parse message exception (233 bytes, 214 unread, last opcode is 0x96 (150), prev opcode is 0xffffffff (-1)): InputMessage eof reached
Packet has been saved to packet.log, you can use it to find what was wrong. (Protocol: 860)

Code:
ProtocolGame parse message exception (233 bytes, 214 unread, last opcode is 0x96 (150), prev opcode is 0xffffffff (-1), proto: 860): InputMessage eof reached
ec 00 59 6b 45 8f e1 00
96 02 00 00 00 e3 0b 01 d1 00 d1 00 45 78 61 6d 70 6c 65 73 20 6f 66 20 75 73 65 3a 0a 21 61 75 74 6f 6c 6f 6f 74 74 65 73 74 20 61 64 64 2c 67 6f 6c 64 20 63 6f 69 6e 0a 21 61 75 74 6f 6c 6f 6f 74 74 65 73 74 20 72 65 6d 6f 76 65 2c 67 6f 6c 64 20 63 6f 69 6e 0a 21 61 75 74 6f 6c 6f 6f 74 74 65 73 74 20 63 6c 65 61 72 0a 21 61 75 74 6f 6c 6f 6f 74 74 65 73 74 20 73 68 6f 77 0a 21 61 75 74 6f 6c 6f 6f 74 74 65 73 74 20 65 64 69 74 0a 0a 7e 41 76 61 69 6c 61 62 6c 65 20 73 6c 6f 74 73 7e 0a 66 72 65 65 41 63 63 6f 75 6e 74 3a 20 31 30 0a 70 72 65 6d 69 75 6d 41 63 63 6f 75 6e 74 3a 20 32 30 0a 63 75 72 72 65 6e 63 79 20 74 6f 20 62 61 6e 6b 3a 20 79 65 73 00 00 00 00
The problem is probably that your client doesn't support text windows with too many characters, just change the script info messages and you're good to go.
 
The problem is probably that your client doesn't support text windows with too many characters, just change the script info messages and you're good to go.
where i do that?

edit: changed player:showTextDialog(20, table.concat(description, '\n'), false) still does not work

Lua:
    /modules/game_actionbar/actionbar.lua:163: in function </modules/game_actionbar/actionbar.lua:154>
ERROR: ProtocolGame parse message exception (233 bytes, 214 unread, last opcode is 0x96 (150), prev opcode is 0xffffffff (-1)): InputMessage eof reached
Packet has been saved to packet.log, you can use it to find what was wrong. (Protocol: 860)
no errors in server console
 
Last edited:
up
to get this working, you need some commit from otcv8? Or a specific protocol version? @ralke how did you get this working? Tried your public repo and is not working there.
 
up
to get this working, you need some commit from otcv8? Or a specific protocol version? @ralke how did you get this working? Tried your public repo and is not working there.
What @Sarah Wesker tried to say if i'm not wrong is just that you should get rid of
Code:
To add articles you just have to write their IDs or names on each line\nfor example:\n\n%s
And change for a shorter message, then add a very specific limit to the loot list, to don't let it exceed the characters admited in a text window.

Try that, and let's see how it goes ^^
Btw, my thoughts are that this is entirely server-side, so don't struggle on client stuff because that's not the problem. Every error from bytes should be left as it is, otherwise you could struggle with cipsoft clients. So my advice is to "fix" directly on .lua

For the post I did before, I honestly get rid of this autoloot system since I didn't need it anymore, but here's a talk with Roddet. I'm a bit lazy right now to traduce, so if you don't understand something just traduce it on google. Basically he told me to check the corpse first and then take the items (just a change on the order of the functions).
1692677897125.png

Hope it helps,
Regards!
 
well changet this
Lua:
   player:showTextDialog(1948, table.concat(description, '\n'), false)
and decreased every line with high amount of numbers like in here for example
Code:
local description = {string.format('~ Your autoloot list, capacity: %d/%d ~\n', #items, getPlayerLimit(player))}
about the us_checkcorpse. didn't add it because i don't use or have the upgrade system, in spite of it, still can't get the script to work.
Code:
local autoloot = {
    talkaction = "!autoloottest",
    storageBase = 50000,
    freeAccountLimit = 10,
    premiumAccountLimit = 20,
    currencyToBank = true
}

local currencyItems = {}
if autoloot.currencyToBank then
    for index, item in pairs(Game.getCurrencyItems()) do
        currencyItems[item:getId()] = true
    end
end

local autolootCache = {}
local textEditRequests = {}

local function getPlayerLimit(player)
    return player:isPremium() and autoloot.premiumAccountLimit or autoloot.freeAccountLimit
end

local function getPlayerAutolootItems(player)
    local limits = getPlayerLimit(player)
    local guid = player:getGuid()
    local itemsCache = autolootCache[guid]
    if itemsCache then
        if #itemsCache > limits then
            local newChache = {unpack(itemsCache, 1, limits)}
            autolootCache[guid] = newChache
            return newChache
        end
        return itemsCache
    end

    local items = {}
    for i = 1, limits do
        local itemType = ItemType(math.max(player.storage[autoloot.storageBase + i], 0))
        if itemType and itemType:getId() ~= 0 then
            items[#items +1] = itemType:getId()
        end
    end

    autolootCache[guid] = items
    return items
end

local function setPlayerAutolootItems(player, newItems)
    local items = getPlayerAutolootItems(player)
    for i = getPlayerLimit(player), 1, -1 do
        local itemId = newItems[i]
        if itemId then
            player.storage[autoloot.storageBase + i] = itemId
            items[i] = itemId
        else
            player.storage[autoloot.storageBase + i] = -1
            table.remove(items, i)
        end
    end
    return true
end

local function addPlayerAutolootItem(player, itemId)
    local items = getPlayerAutolootItems(player)
    for _, id in pairs(items) do
        if itemId == id then
            return false
        end
    end
    items[#items +1] = itemId
    return setPlayerAutolootItems(player, items)
end

local function removePlayerAutolootItem(player, itemId)
    local items = getPlayerAutolootItems(player)
    for i, id in pairs(items) do
        if itemId == id then
            table.remove(items, i)
            return setPlayerAutolootItems(player, items)
        end
    end
    return false
end

local function hasPlayerAutolootItem(player, itemId)
    for _, id in pairs(getPlayerAutolootItems(player)) do
        if itemId == id then
            return true
        end
    end
    return false
end

local ec = EventCallback

function ec.onDropLoot(monster, corpse)
    if not corpse:getType():isContainer() then
        return
    end

    local corpseOwner = Player(corpse:getCorpseOwner())
    local items = corpse:getItems()
    local warningCapacity = false
    for _, item in pairs(items) do
        local itemId = item:getId()
        if hasPlayerAutolootItem(corpseOwner, itemId) then
            if currencyItems[itemId] then
                local worth = item:getWorth()
                corpseOwner:setBankBalance(corpseOwner:getBankBalance() + worth)
                corpseOwner:sendTextMessage(MESSAGE_STATUS_SMALL, string.format("Your balance increases by %d gold coins.", worth))
                item:remove()
            elseif not item:moveTo(corpseOwner, 0) then
                warningCapacity = true
            end
        end
    end

    if warningCapacity then
        corpseOwner:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You no have capacity.")
    end
end

ec:register(3)

local talkAction = TalkAction(autoloot.talkaction)

function talkAction.onSay(player, words, param, type)
    local split = param:splitTrimmed(",")
    local action = split[1]
    if not action then
        player:showTextDialog(2160, string.format("Examples of use:\n%s add,gold", words, words, words, words, words, autoloot.freeAccountLimit, autoloot.premiumAccountLimit, autoloot.currencyToBank and "yes" or "no"), false)
        return false
    end

    if action == "clear" then
        setPlayerAutolootItems(player, {})
        player:sendCancelMessage("Autoloot list cleaned.")
        return false
    elseif action == "show" then
        local items = getPlayerAutolootItems(player)
        local description = {string.format('~ Your autoloot list, capacity: %d/%d ~\n', #items, getPlayerLimit(player))}
        for i, itemId in pairs(items) do
            description[#description +1] = string.format("%d) %s", i, ItemType(itemId):getName())
        end
        player:showTextDialog(1948, table.concat(description, '\n'), false)
        return false
    elseif action == "edit" then
        local items = getPlayerAutolootItems(player)
        if #items == 0 then
            -- Example
            items = {2160,2672,2432}
        end
        local description = {}
        for i, itemId in pairs(items) do
            description[#description +1] = ItemType(itemId):getName()
        end
        player:registerEvent("autolootTextEdit")
        player:showTextDialog(1948, string.format("To add articles you just have to write their names", table.concat(description, '\n')), true, 666)
        textEditRequests[player:getGuid()] = true
        return false
    end

    local function getItemType()
        local itemType = ItemType(split[2])
        if not itemType or itemType:getId() == 0 then
            itemType = ItemType(math.max(tonumber(split[2]) or 0), 0)
            if not itemType or itemType:getId() == 0 then
                player:sendCancelMessage(string.format("The item %s does not exists!", split[2]))
                return false
            end
        end
        return itemType
    end

    if action == "add" then
        local itemType = getItemType()
        if itemType then
            local limits = getPlayerLimit(player)
            if #getPlayerAutolootItems(player) >= limits then
                player:sendCancelMessage(string.format("Your auto loot only allows you to add %d items.", limits))
                return false
            end

            if addPlayerAutolootItem(player, itemType:getId()) then
                player:sendCancelMessage(string.format("Perfect you have added to the list: %s", itemType:getName()))
            else
                player:sendCancelMessage(string.format("The item %s already exists!", itemType:getName()))
            end
        end
        return false
    elseif action == "remove" then
        local itemType = getItemType()
        if itemType then
            if removePlayerAutolootItem(player, itemType:getId()) then
                player:sendCancelMessage(string.format("Perfect you have removed to the list : %s", itemType:getName()))
            else
                player:sendCancelMessage(string.format("The item %s does not exists.", itemType:getName()))
            end
        end
        return false
    end

    return false
end

talkAction:separator(" ")
talkAction:register()

local creatureEvent = CreatureEvent("autolootCleanCache")

function creatureEvent.onLogout(player)
    setPlayerAutolootItems(player, getPlayerAutolootItems(player))
    autolootCache[player:getGuid()] = nil
    return true
end

creatureEvent:register()

creatureEvent = CreatureEvent("autolootTextEdit")

function creatureEvent.onTextEdit(player, item, text)
    player:unregisterEvent("autolootTextEdit")

    local split = text:splitTrimmed("\n")
    local items = {}
    for index, name in pairs(split) do repeat
        local itemType = ItemType(name)
        if not itemType or itemType:getId() == 0 then
            itemType = ItemType(tonumber(name))
            if not itemType or itemType:getId() == 0 then
                break
            end

            break
        end

        items[#items +1] = itemType:getId()
    until true end
    setPlayerAutolootItems(player, items)
    player:sendCancelMessage(string.format("Perfect, you have modified the list of articles manually."))
    return true
end

creatureEvent:register()
no erros in console server but in terminal this appears
Code:
ERROR: ProtocolGame parse message exception (133 bytes, 114 unread, last opcode is 0x96 (150), prev opcode is 0xffffffff (-1)): InputMessage eof reached
Packet has been saved to packet.log, you can use it to find what was wrong. (Protocol: 860)
 
where i do that?

edit: changed player:showTextDialog(20, table.concat(description, '\n'), false) still does not work

Lua:
    /modules/game_actionbar/actionbar.lua:163: in function </modules/game_actionbar/actionbar.lua:154>
ERROR: ProtocolGame parse message exception (233 bytes, 214 unread, last opcode is 0x96 (150), prev opcode is 0xffffffff (-1)): InputMessage eof reached
Packet has been saved to packet.log, you can use it to find what was wrong. (Protocol: 860)
no errors in server console
Lua:
local autoloot = {
    talkaction = "!autoloottest",
    storageBase = 50000,
    freeAccountLimit = 10,
    premiumAccountLimit = 20,
    currencyToBank = true
}

local currencyItems = {}
if autoloot.currencyToBank then
    for index, item in pairs(Game.getCurrencyItems()) do
        currencyItems[item:getId()] = true
    end
end

local autolootCache = {}
local textEditRequests = {}
local function getPlayerLimit(player)
    return player:isPremium() and autoloot.premiumAccountLimit or autoloot.freeAccountLimit
end

local function getPlayerAutolootItems(player)
    local limits = getPlayerLimit(player)
    local guid = player:getGuid()
    local itemsCache = autolootCache[guid]
    if itemsCache then
        if #itemsCache > limits then
            local newChache = {unpack(itemsCache, 1, limits)}
            autolootCache[guid] = newChache
            return newChache
        end
        return itemsCache
    end

    local items = {}
    for i = 1, limits do
        local itemType = ItemType(math.max(player.storage[autoloot.storageBase + i], 0))
        if itemType and itemType:getId() ~= 0 then
            items[#items +1] = itemType:getId()
        end
    end

    autolootCache[guid] = items
    return items
end

local function setPlayerAutolootItems(player, newItems)
    local items = getPlayerAutolootItems(player)
    for i = getPlayerLimit(player), 1, -1 do
        local itemId = newItems[i]
        if itemId then
            player.storage[autoloot.storageBase + i] = itemId
            items[i] = itemId
        else
            player.storage[autoloot.storageBase + i] = -1
            table.remove(items, i)
        end
    end
    return true
end

local function addPlayerAutolootItem(player, itemId)
    local items = getPlayerAutolootItems(player)
    for _, id in pairs(items) do
        if itemId == id then
            return false
        end
    end

    items[#items +1] = itemId
    return setPlayerAutolootItems(player, items)
end

local function removePlayerAutolootItem(player, itemId)
    local items = getPlayerAutolootItems(player)
    for i, id in pairs(items) do
        if itemId == id then
            table.remove(items, i)
            return setPlayerAutolootItems(player, items)
        end
    end
    return false
end

local function hasPlayerAutolootItem(player, itemId)
    for _, id in pairs(getPlayerAutolootItems(player)) do
        if itemId == id then
            return true
        end
    end
    return false
end

local ec = EventCallback

function ec.onDropLoot(monster, corpse)
    if not corpse:getType():isContainer() then
        return
    end

    local corpseOwner = Player(corpse:getCorpseOwner())
    local items = corpse:getItems()
    local warningCapacity = false
    for _, item in pairs(items) do
        local itemId = item:getId()
        if hasPlayerAutolootItem(corpseOwner, itemId) then
            if currencyItems[itemId] then
                local worth = item:getWorth()
                corpseOwner:setBankBalance(corpseOwner:getBankBalance() + worth)
                corpseOwner:sendTextMessage(MESSAGE_STATUS_SMALL, string.format("Your balance increases by %d gold coins.", worth))
                item:remove()
            elseif not item:moveTo(corpseOwner, 0) then
                warningCapacity = true
            end
        end
    end

    if warningCapacity then
        corpseOwner:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You no have capacity.")
    end
end

ec:register(3)

local talkAction = TalkAction(autoloot.talkaction)

function talkAction.onSay(player, words, param, type)
    local split = param:splitTrimmed(",")
    local action = split[1]
    if not action then
        player:sendCancelMessage("You need to specify an action, !autoloot <add/remove/clear/show/edit> <item>.")
        return false
    end

    if action == "clear" then
        setPlayerAutolootItems(player, {})
        player:sendCancelMessage("Autoloot list cleaned.")
        return false
    elseif action == "show" then
        local items = getPlayerAutolootItems(player)
        local description = {string.format('~ Your autoloot list, capacity: %d/%d ~\n', #items, getPlayerLimit(player))}
        for i, itemId in pairs(items) do
            description[#description +1] = string.format("%d) %s", i, ItemType(itemId):getName())
        end

        player:showTextDialog(1948, table.concat(description, '\n'), false)
        return false
    elseif action == "edit" then
        local items = getPlayerAutolootItems(player)
        if #items == 0 then
            -- Example
            items = {2160,2672,2432}
        end
        local description = {}
        for i, itemId in pairs(items) do
            description[#description +1] = ItemType(itemId):getName()
        end

        player:registerEvent("autolootTextEdit")
        player:showTextDialog(1948, string.format("To add articles you just have to write their IDs or names on each line\nfor example:\n\n%s", table.concat(description, '\n')), true, 666)
        textEditRequests[player:getGuid()] = true
        return false
    end

    local function getItemType()
        local itemType = ItemType(split[2])
        if not itemType or itemType:getId() == 0 then
            itemType = ItemType(math.max(tonumber(split[2]) or 0), 0)
            if not itemType or itemType:getId() == 0 then
                player:sendCancelMessage(string.format("The item %s does not exists!", split[2]))
                return false
            end
        end
        return itemType
    end

    if action == "add" then
        local itemType = getItemType()
        if itemType then
            local limits = getPlayerLimit(player)
            if #getPlayerAutolootItems(player) >= limits then
                player:sendCancelMessage(string.format("Your auto loot only allows you to add %d items.", limits))
                return false
            end

            if addPlayerAutolootItem(player, itemType:getId()) then
                player:sendCancelMessage(string.format("Perfect you have added to the list: %s", itemType:getName()))
            else
                player:sendCancelMessage(string.format("The item %s already exists!", itemType:getName()))
            end
        end
        return false
    elseif action == "remove" then
        local itemType = getItemType()
        if itemType then
            if removePlayerAutolootItem(player, itemType:getId()) then
                player:sendCancelMessage(string.format("Perfect you have removed to the list the article: %s", itemType:getName()))
            else
                player:sendCancelMessage(string.format("The item %s does not exists in the list.", itemType:getName()))
            end
        end
        return false
    end
    return false
end

talkAction:separator(" ")
talkAction:register()

local creatureEvent = CreatureEvent("autolootCleanCache")

function creatureEvent.onLogout(player)
    setPlayerAutolootItems(player, getPlayerAutolootItems(player))
    autolootCache[player:getGuid()] = nil
    return true
end

creatureEvent:register()

creatureEvent = CreatureEvent("autolootTextEdit")

function creatureEvent.onTextEdit(player, item, text)
    player:unregisterEvent("autolootTextEdit")
    local split = text:splitTrimmed("\n")
    local items = {}
    for index, name in pairs(split) do repeat
        local itemType = ItemType(name)
        if not itemType or itemType:getId() == 0 then
            itemType = ItemType(tonumber(name))
            if not itemType or itemType:getId() == 0 then
                break
            end
            break
        end
        items[#items +1] = itemType:getId()
    until true end
    setPlayerAutolootItems(player, items)
    player:sendCancelMessage(string.format("Perfect, you have modified the list of articles manually."))
    return true
end

creatureEvent:register()
 
Lua:
local autoloot = {
    talkaction = "!autoloottest",
    storageBase = 50000,
    freeAccountLimit = 10,
    premiumAccountLimit = 20,
    currencyToBank = true
}

local currencyItems = {}
if autoloot.currencyToBank then
    for index, item in pairs(Game.getCurrencyItems()) do
        currencyItems[item:getId()] = true
    end
end

local autolootCache = {}
local textEditRequests = {}
local function getPlayerLimit(player)
    return player:isPremium() and autoloot.premiumAccountLimit or autoloot.freeAccountLimit
end

local function getPlayerAutolootItems(player)
    local limits = getPlayerLimit(player)
    local guid = player:getGuid()
    local itemsCache = autolootCache[guid]
    if itemsCache then
        if #itemsCache > limits then
            local newChache = {unpack(itemsCache, 1, limits)}
            autolootCache[guid] = newChache
            return newChache
        end
        return itemsCache
    end

    local items = {}
    for i = 1, limits do
        local itemType = ItemType(math.max(player.storage[autoloot.storageBase + i], 0))
        if itemType and itemType:getId() ~= 0 then
            items[#items +1] = itemType:getId()
        end
    end

    autolootCache[guid] = items
    return items
end

local function setPlayerAutolootItems(player, newItems)
    local items = getPlayerAutolootItems(player)
    for i = getPlayerLimit(player), 1, -1 do
        local itemId = newItems[i]
        if itemId then
            player.storage[autoloot.storageBase + i] = itemId
            items[i] = itemId
        else
            player.storage[autoloot.storageBase + i] = -1
            table.remove(items, i)
        end
    end
    return true
end

local function addPlayerAutolootItem(player, itemId)
    local items = getPlayerAutolootItems(player)
    for _, id in pairs(items) do
        if itemId == id then
            return false
        end
    end

    items[#items +1] = itemId
    return setPlayerAutolootItems(player, items)
end

local function removePlayerAutolootItem(player, itemId)
    local items = getPlayerAutolootItems(player)
    for i, id in pairs(items) do
        if itemId == id then
            table.remove(items, i)
            return setPlayerAutolootItems(player, items)
        end
    end
    return false
end

local function hasPlayerAutolootItem(player, itemId)
    for _, id in pairs(getPlayerAutolootItems(player)) do
        if itemId == id then
            return true
        end
    end
    return false
end

local ec = EventCallback

function ec.onDropLoot(monster, corpse)
    if not corpse:getType():isContainer() then
        return
    end

    local corpseOwner = Player(corpse:getCorpseOwner())
    local items = corpse:getItems()
    local warningCapacity = false
    for _, item in pairs(items) do
        local itemId = item:getId()
        if hasPlayerAutolootItem(corpseOwner, itemId) then
            if currencyItems[itemId] then
                local worth = item:getWorth()
                corpseOwner:setBankBalance(corpseOwner:getBankBalance() + worth)
                corpseOwner:sendTextMessage(MESSAGE_STATUS_SMALL, string.format("Your balance increases by %d gold coins.", worth))
                item:remove()
            elseif not item:moveTo(corpseOwner, 0) then
                warningCapacity = true
            end
        end
    end

    if warningCapacity then
        corpseOwner:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You no have capacity.")
    end
end

ec:register(3)

local talkAction = TalkAction(autoloot.talkaction)

function talkAction.onSay(player, words, param, type)
    local split = param:splitTrimmed(",")
    local action = split[1]
    if not action then
        player:sendCancelMessage("You need to specify an action, !autoloot <add/remove/clear/show/edit> <item>.")
        return false
    end

    if action == "clear" then
        setPlayerAutolootItems(player, {})
        player:sendCancelMessage("Autoloot list cleaned.")
        return false
    elseif action == "show" then
        local items = getPlayerAutolootItems(player)
        local description = {string.format('~ Your autoloot list, capacity: %d/%d ~\n', #items, getPlayerLimit(player))}
        for i, itemId in pairs(items) do
            description[#description +1] = string.format("%d) %s", i, ItemType(itemId):getName())
        end

        player:showTextDialog(1948, table.concat(description, '\n'), false)
        return false
    elseif action == "edit" then
        local items = getPlayerAutolootItems(player)
        if #items == 0 then
            -- Example
            items = {2160,2672,2432}
        end
        local description = {}
        for i, itemId in pairs(items) do
            description[#description +1] = ItemType(itemId):getName()
        end

        player:registerEvent("autolootTextEdit")
        player:showTextDialog(1948, string.format("To add articles you just have to write their IDs or names on each line\nfor example:\n\n%s", table.concat(description, '\n')), true, 666)
        textEditRequests[player:getGuid()] = true
        return false
    end

    local function getItemType()
        local itemType = ItemType(split[2])
        if not itemType or itemType:getId() == 0 then
            itemType = ItemType(math.max(tonumber(split[2]) or 0), 0)
            if not itemType or itemType:getId() == 0 then
                player:sendCancelMessage(string.format("The item %s does not exists!", split[2]))
                return false
            end
        end
        return itemType
    end

    if action == "add" then
        local itemType = getItemType()
        if itemType then
            local limits = getPlayerLimit(player)
            if #getPlayerAutolootItems(player) >= limits then
                player:sendCancelMessage(string.format("Your auto loot only allows you to add %d items.", limits))
                return false
            end

            if addPlayerAutolootItem(player, itemType:getId()) then
                player:sendCancelMessage(string.format("Perfect you have added to the list: %s", itemType:getName()))
            else
                player:sendCancelMessage(string.format("The item %s already exists!", itemType:getName()))
            end
        end
        return false
    elseif action == "remove" then
        local itemType = getItemType()
        if itemType then
            if removePlayerAutolootItem(player, itemType:getId()) then
                player:sendCancelMessage(string.format("Perfect you have removed to the list the article: %s", itemType:getName()))
            else
                player:sendCancelMessage(string.format("The item %s does not exists in the list.", itemType:getName()))
            end
        end
        return false
    end
    return false
end

talkAction:separator(" ")
talkAction:register()

local creatureEvent = CreatureEvent("autolootCleanCache")

function creatureEvent.onLogout(player)
    setPlayerAutolootItems(player, getPlayerAutolootItems(player))
    autolootCache[player:getGuid()] = nil
    return true
end

creatureEvent:register()

creatureEvent = CreatureEvent("autolootTextEdit")

function creatureEvent.onTextEdit(player, item, text)
    player:unregisterEvent("autolootTextEdit")
    local split = text:splitTrimmed("\n")
    local items = {}
    for index, name in pairs(split) do repeat
        local itemType = ItemType(name)
        if not itemType or itemType:getId() == 0 then
            itemType = ItemType(tonumber(name))
            if not itemType or itemType:getId() == 0 then
                break
            end
            break
        end
        items[#items +1] = itemType:getId()
    until true end
    setPlayerAutolootItems(player, items)
    player:sendCancelMessage(string.format("Perfect, you have modified the list of articles manually."))
    return true
end

creatureEvent:register()
Works. thank you !
, a guy is crashing the server and don't want to tell me how
 
Last edited:
Back
Top