• 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!

Feature Auto Loot [TFS 1.3]

jgjfys.png

new erros


Code:
Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/autoloot.lua:onSay
data/talkactions/scripts/autoloot.lua:3: attempt to call method 'getAutoLootList' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootList'
        data/talkactions/scripts/autoloot.lua:3: in function <data/talkactions/scripts/autoloot.lua:1>

Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/addautoloot.lua:onSay
data/talkactions/scripts/addautoloot.lua:11: attempt to call method 'getAutoLootItem' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootItem'
        data/talkactions/scripts/addautoloot.lua:11: in function <data/talkactions/scripts/addautoloot.lua:1>

Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/autoloot.lua:onSay
data/talkactions/scripts/autoloot.lua:3: attempt to call method 'getAutoLootList' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootList'
        data/talkactions/scripts/autoloot.lua:3: in function <data/talkactions/scripts/autoloot.lua:1>

Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/autoloot.lua:onSay
data/talkactions/scripts/autoloot.lua:3: attempt to call method 'getAutoLootList' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootList'
        data/talkactions/scripts/autoloot.lua:3: in function <data/talkactions/scripts/autoloot.lua:1>

Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/remautoloot.lua:onSay
data/talkactions/scripts/remautoloot.lua:12: attempt to call method 'getAutoLootItem' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootItem'
        data/talkactions/scripts/remautoloot.lua:12: in function <data/talkactions/scripts/remautoloot.lua:1>
 
just redo all the steps, you're doing something wrong and skipping something
 
Thanks you static, I tested this mod and doesn't work for my ot. It's because I don't have any corpses in the items.otb because the corpses from my server are containers jajaja, then I have made some changes and finally it's works. I made this: In some place from the scripts, appears this:
if tile.uid > 0 and isCorpse(tile.uid) then
and I have changed to:
if tile.uid > 0 and (isContainer(tile.uid) or isCorpse(tile.uid)) then
and it's works!
 
I was bored so i did this code, thanks @Thexamx for the general help.

pZbGxtR.gif


In player.h, above
Code:
std::unordered_set<uint32_t> attackedSet;
Add:
Code:
std::set<uint32_t> autoLootList;

Below:
Code:
bool hasLearnedInstantSpell(const std::string& spellName) const;
Add:
Code:
void addAutoLootItem(uint16_t itemId);
void removeAutoLootItem(uint16_t itemId);
bool getAutoLootItem(uint16_t itemId);

In player.cpp, add these lines:
Code:
void Player::addAutoLootItem(uint16_t itemId)
{
    autoLootList.insert(itemId);
}

void Player::removeAutoLootItem(uint16_t itemId)
{
    autoLootList.erase(itemId);
}

bool Player::getAutoLootItem(const uint16_t itemId)
{
    return autoLootList.find(itemId) != autoLootList.end();
}

In monsters.cpp, before:
Code:
if (!owner || owner->getStaminaMinutes() > 840) {
Add:
Code:
std::string autolooted = "";

Replace:
Code:
corpse->internalAddThing(item);
With:
Code:
                if (owner->getAutoLootItem(item->getID())) {
                    g_game.internalPlayerAddItem(owner, item, true, CONST_SLOT_WHEREEVER);
                    autolooted = autolooted + ", " + item->getNameDescription();
                } else if (g_game.internalAddItem(corpse, item) != RETURNVALUE_NOERROR) {
                   corpse->internalAddThing(item);
               }

Below:
Code:
std::ostringstream ss;
Add:
Code:
std::string lootMsg = corpse->getContentDescription();

And replace
Code:
ss << "Loot of " << nameDescription << ": " << corpse->getContentDescription();
With:
Code:
            if (autolooted != "" and corpse->getContentDescription() == "nothing") {
                lootMsg = autolooted.erase(0,2) + " that was auto looted";
            } else if (autolooted != "") {
                lootMsg =  corpse->getContentDescription() + " and " + autolooted.erase(0,2) + " was auto looted.";
            }

In luascript.cpp, add these lines:
Code:
//Autoloot wrote by Psychonaut#4421

int LuaScriptInterface::luaPlayerAddAutoLootItem(lua_State* L)
{
    // player:addAutoLootItem(itemId)
    Player* player = getUserdata<Player>(L, 1);
    if (!player) {
        lua_pushnil(L);
        return 1;
    }

    uint16_t itemId;
    if (isNumber(L, 2)) {
        itemId = getNumber<uint16_t>(L, 2);
    } else {
        itemId = Item::items.getItemIdByName(getString(L, 2));
        if (itemId == 0) {
            lua_pushnil(L);
            return 1;
        }
    }
    player->addAutoLootItem(itemId);
    pushBoolean(L, true);
    return 1;
}

int LuaScriptInterface::luaPlayerRemoveAutoLootItem(lua_State* L)
{
    // player:removeAutoLootItem(itemId)
    Player* player = getUserdata<Player>(L, 1);
    if (!player) {
        lua_pushnil(L);
        return 1;
    }

    uint16_t itemId;
    if (isNumber(L, 2)) {
        itemId = getNumber<uint16_t>(L, 2);
    } else {
        itemId = Item::items.getItemIdByName(getString(L, 2));
        if (itemId == 0) {
            lua_pushnil(L);
            return 1;
        }
    }
 
    player->removeAutoLootItem(itemId);
    pushBoolean(L, true);

    return 1;
}

int LuaScriptInterface::luaPlayerGetAutoLootItem(lua_State* L)
{
    // player:getAutoLootItem(itemId)
    Player* player = getUserdata<Player>(L, 1);
    if (!player) {
        lua_pushnil(L);
        return 1;
    }

    uint16_t itemId;
    if (isNumber(L, 2)) {
        itemId = getNumber<uint16_t>(L, 2);
    } else {
        itemId = Item::items.getItemIdByName(getString(L, 2));
        if (itemId == 0) {
            lua_pushnil(L);
            return 1;
        }
    }
 
    if (player->getAutoLootItem(itemId)) {
        pushBoolean(L, true);
    } else {
        pushBoolean(L, false);
    }

    return 1;
}

int LuaScriptInterface::luaPlayerGetAutoLootList(lua_State* L)
{
    // player:getAutoLootList()
    Player* player = getUserdata<Player>(L, 1);

    if (player) {
        std::set<uint32_t> value = player->autoLootList;
   
        if (value.size() == 0) {
          lua_pushnil(L);
          return 1;
        }

        int index = 0;
        lua_createtable(L, value.size(), 0);
        for(auto i : value) {
            lua_pushnumber(L, i);
            lua_rawseti(L, -2, ++index);
        }
   
    } else {
        lua_pushnil(L);
    }

    return 1;
}

And in iologindata.cpp, below:
Code:
//load storage map
query.str(std::string());
query << "SELECT `key`, `value` FROM `player_storage` WHERE `player_id` = " << player->getGUID();
if ((result = db.storeQuery(query.str()))) {
    do {
        player->addStorageValue(result->getNumber<uint32_t>("key"), result->getNumber<int32_t>("value"), true);
    } while (result->next());
}

Add:

Code:
//load autoloot list set
query.str(std::string());
query << "SELECT `autoloot_list` FROM `player_autoloot` WHERE `player_id` = " << player->getGUID();
if ((result = db.storeQuery(query.str()))) {
    unsigned long lootlistSize;
    const char* autolootlist = result->getStream("autoloot_list", lootlistSize);
    PropStream propStreamList;
    propStreamList.init(autolootlist, lootlistSize);

    int16_t value;
    int16_t item = propStreamList.read<int16_t>(value);
    while (item) {
        player->addAutoLootItem(value);
        item = propStreamList.read<int16_t>(value);
    }
}

And above:
Code:
//save inbox items

Add:
Code:
//save autolootlist
query.str(std::string());
query << "DELETE FROM `player_autoloot` WHERE `player_id` = " << player->getGUID();
if (!db.executeQuery(query.str())) {
    return false;
}

PropWriteStream propWriteStreamAutoLoot;

for (auto i : player->autoLootList) {
    propWriteStreamAutoLoot.write<uint16_t>(i);
}

size_t lootlistSize;
const char* autolootlist = propWriteStreamAutoLoot.getStream(lootlistSize);

query.str(std::string());

DBInsert autolootQuery("INSERT INTO `player_autoloot` (`player_id`, `autoloot_list`) VALUES ");

    query << player->getGUID() << ',' << db.escapeBlob(autolootlist, lootlistSize);
    if (!autolootQuery.addRow(query)) {
        return false;
    }

if (!autolootQuery.execute()) {
    return false;
}

Note that in both you could use the same stream as conditions and clear it, but idk what you changed or not in the code.

Go to your database
and create a new table named player_autoloot with id(primary/auto increment), player_id(int) and autoloot_list(blob). Something like:

Code:
CREATE TABLE player_autoloot (
    id int NOT NULL AUTO_INCREMENT,
    player_id int NOT NULL,
    autoloot_list blob,
    PRIMARY KEY (id)
);

And then go to data/lib/compat/compat.lua(or where you wanna use it) and add these lines:
Lua:
--AutoLoot written by Psychonaut#4421
function getPlayerAutoLootItem(cid, itemId) local p = Player(cid) return p ~= nil and p:getAutoLootItem(itemId) or false end
function getPlayerAutoLootList(cid) local p = Player(cid) return p ~= nil and p:getAutoLootList() or false end
function removePlayerAutoLootItem(cid, itemId) local p = Player(cid) return p ~= nil and p:removeAutoLootItem(itemId) or false end
function addPlayerAutoLootItem(cid, itemId) local p = Player(cid) return p ~= nil and p:addAutoLootItem(itemId) or false end

These are the commands:

xml:
Code:
<talkaction words="!autoloot" script="autoloot.lua" />
<talkaction words="!add" separator=" " script="addautoloot.lua" />
<talkaction words="!remove" separator=" " script="remautoloot.lua" />

Lua:
function onSay(player, words, param)
    local list = "You're auto looting: "
    local alist = player:getAutoLootList()
 
    if alist then
        for _, item in ipairs(alist) do
            list = list .. (ItemType(item)):getName() .. ", "
        end
    else
        player:sendCancelMessage("The list is empty.")
        return false
    end
    player:sendTextMessage(MESSAGE_INFO_DESCR, list:sub(1, -3))
    return false
end
Lua:
function onSay(player, words, param)
    local itemType = ItemType(param)

    if itemType:getId() == 0 then
        itemType = ItemType(tonumber(param))
        if itemType:getName() == '' then
            player:sendCancelMessage("There is no item with that id or name.")
            return false
        end
    end
    if player:getAutoLootItem(itemType:getId()) then
        player:sendCancelMessage("You're already autolooting this item.")
        return false
    end

    player:addAutoLootItem(itemType:getId())
    player:sendTextMessage(MESSAGE_INFO_DESCR, "You're now auto looting " .. itemType:getName())
    return false
end
Lua:
function onSay(player, words, param)
    local itemType = ItemType(param)
 
    if itemType:getId() == 0 then
        itemType = ItemType(tonumber(param))
        if itemType:getName() == '' then
            player:sendCancelMessage("There is no item with that id or name.")
            return false
        end
    end

    if player:getAutoLootItem(itemType:getId()) then
        player:removeAutoLootItem(itemType:getId())
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You're not auto looting " .. itemType:getName() .. " anymore.")
    else
        player:sendCancelMessage("You're not autolooting this item.")
    end

    return false
end
The function can do a check for id/names but i'm doing in lua as i already need to getting the itemType anyway.
Sometimes when i copy part of a code here the identation goes away(and i can't fix it here), so tab it yourself where it happened.

You can call these functions in a npc if you doesn't wanna use talkactions or anywhere that you want.

what is the max and min? where I can see this and if I need add more slots for players? <3
 
jgjfys.png

new erros


Code:
Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/autoloot.lua:onSay
data/talkactions/scripts/autoloot.lua:3: attempt to call method 'getAutoLootList' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootList'
        data/talkactions/scripts/autoloot.lua:3: in function <data/talkactions/scripts/autoloot.lua:1>

Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/addautoloot.lua:onSay
data/talkactions/scripts/addautoloot.lua:11: attempt to call method 'getAutoLootItem' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootItem'
        data/talkactions/scripts/addautoloot.lua:11: in function <data/talkactions/scripts/addautoloot.lua:1>

Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/autoloot.lua:onSay
data/talkactions/scripts/autoloot.lua:3: attempt to call method 'getAutoLootList' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootList'
        data/talkactions/scripts/autoloot.lua:3: in function <data/talkactions/scripts/autoloot.lua:1>

Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/autoloot.lua:onSay
data/talkactions/scripts/autoloot.lua:3: attempt to call method 'getAutoLootList' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootList'
        data/talkactions/scripts/autoloot.lua:3: in function <data/talkactions/scripts/autoloot.lua:1>

Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/remautoloot.lua:onSay
data/talkactions/scripts/remautoloot.lua:12: attempt to call method 'getAutoLootItem' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootItem'
        data/talkactions/scripts/remautoloot.lua:12: in function <data/talkactions/scripts/remautoloot.lua:1>

Did you manage to fix this? I have checked all the implemented codes in the build files, everything is correct. I can compile without errors. But still i get this error like you?
Is this outdated ?
 
what is wrong?
C++:
/home/.ots/src/player.h:1378:8: error: ‘set’ in namespace ‘std’ does not name a                                                                                         template type
   std::set<uint32_t>autoLootList;
        ^
CMakeFiles/tfs.dir/build.make:119: recipe for target 'CMakeFiles/tfs.dir/src/act                                                                                        ions.cpp.o' failed
make[2]: *** [CMakeFiles/tfs.dir/src/actions.cpp.o] Error 1
CMakeFiles/Makefile2:122: recipe for target 'CMakeFiles/tfs.dir/all' failed
make[1]: *** [CMakeFiles/tfs.dir/all] Error 2
Makefile:76: recipe for target 'all' failed
make: *** [all] Error 2
 
jgjfys.png

new erros


Code:
Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/autoloot.lua:onSay
data/talkactions/scripts/autoloot.lua:3: attempt to call method 'getAutoLootList' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootList'
        data/talkactions/scripts/autoloot.lua:3: in function <data/talkactions/scripts/autoloot.lua:1>

Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/addautoloot.lua:onSay
data/talkactions/scripts/addautoloot.lua:11: attempt to call method 'getAutoLootItem' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootItem'
        data/talkactions/scripts/addautoloot.lua:11: in function <data/talkactions/scripts/addautoloot.lua:1>

Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/autoloot.lua:onSay
data/talkactions/scripts/autoloot.lua:3: attempt to call method 'getAutoLootList' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootList'
        data/talkactions/scripts/autoloot.lua:3: in function <data/talkactions/scripts/autoloot.lua:1>

Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/autoloot.lua:onSay
data/talkactions/scripts/autoloot.lua:3: attempt to call method 'getAutoLootList' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootList'
        data/talkactions/scripts/autoloot.lua:3: in function <data/talkactions/scripts/autoloot.lua:1>

Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/remautoloot.lua:onSay
data/talkactions/scripts/remautoloot.lua:12: attempt to call method 'getAutoLootItem' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootItem'
        data/talkactions/scripts/remautoloot.lua:12: in function <data/talkactions/scripts/remautoloot.lua:1>

It's happening the same here.

I think the problem is in:
C++:
std::set<uint32_t> autoLootList;

because:
 
It's happening the same here.

I think the problem is in:
C++:
std::set<uint32_t> autoLootList;

because:

who fixed this?

jgjfys.png

new erros


Code:
Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/autoloot.lua:onSay
data/talkactions/scripts/autoloot.lua:3: attempt to call method 'getAutoLootList' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootList'
        data/talkactions/scripts/autoloot.lua:3: in function <data/talkactions/scripts/autoloot.lua:1>

Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/addautoloot.lua:onSay
data/talkactions/scripts/addautoloot.lua:11: attempt to call method 'getAutoLootItem' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootItem'
        data/talkactions/scripts/addautoloot.lua:11: in function <data/talkactions/scripts/addautoloot.lua:1>

Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/autoloot.lua:onSay
data/talkactions/scripts/autoloot.lua:3: attempt to call method 'getAutoLootList' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootList'
        data/talkactions/scripts/autoloot.lua:3: in function <data/talkactions/scripts/autoloot.lua:1>

Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/autoloot.lua:onSay
data/talkactions/scripts/autoloot.lua:3: attempt to call method 'getAutoLootList' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootList'
        data/talkactions/scripts/autoloot.lua:3: in function <data/talkactions/scripts/autoloot.lua:1>

Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/remautoloot.lua:onSay
data/talkactions/scripts/remautoloot.lua:12: attempt to call method 'getAutoLootItem' (a nil value)
stack traceback:
        [C]: in function 'getAutoLootItem'
        data/talkactions/scripts/remautoloot.lua:12: in function <data/talkactions/scripts/remautoloot.lua:1>


same problem here, did u solved?
 
Last edited by a moderator:
[ 37%] Building CXX object CMakeFiles/tfs.dir/src/iologindata.cpp.o
/home/rmglasspe/servidor/source/src/iologindata.cpp: In static member function ‘ static bool IOLoginData::loadPlayer(Player*, DBResult_ptr)’:
/home/rmglasspe/servidor/source/src/iologindata.cpp:704:26: error: request for m ember ‘storeQuery’ in ‘db’, which is of pointer type ‘Database*’ (maybe you mean t to use ‘->’ ?)
if ((result = db.storeQuery(query.str()))) {
^
/home/rmglasspe/servidor/source/src/iologindata.cpp: In static member function ‘ static bool IOLoginData::savePlayer(Player*)’:
/home/rmglasspe/servidor/source/src/iologindata.cpp:1035:17: error: request for member ‘executeQuery’ in ‘db’, which is of pointer type ‘Database*’ (maybe you m eant to use ‘->’ ?)
if (!db.executeQuery(query.str())) {
^
/home/rmglasspe/servidor/source/src/iologindata.cpp:1052:45: error: request for member ‘escapeBlob’ in ‘db’, which is of pointer type ‘Database*’ (maybe you mea nt to use ‘->’ ?)
query << player->getGUID() << ',' << db.escapeBlob(autolootlist, lootlistSi ze);
^
make[2]: *** [CMakeFiles/tfs.dir/src/iologindata.cpp.o] Error 1
make[1]: *** [CMakeFiles/tfs.dir/all] Error 2
make: *** [all] Error 2

i got this, anyone can helpme ?
 
Back
Top