Some words...
Yo. I developed this system as a method of study. (C++). If u found some bug, report it here and I will fix that.
thanks for @Delusion for the help. This system have was inspired in Auto Loot System by @psychonaut.
This system was created in the latest version of tfs.
How it works?
Simple, when you kill some monster and open the corpse (you need click in corpse to loot), the items go for you character.
Installation
in actions.cpp, find:
and change it for:
in player.h, below
Add this
below that:
Add this
in player.cpp, in the end... add
in luascript.cpp, find
add that below
yet in luascript.cpp, find this function
below this whole function, add
in luascript.h, find
add below
And in iologindata.cpp, below:
add
And above:
add
now, go to your database and execute this query:
go your data/scripts/talkactions and create this file:
autoloot.lua
That's it, I hope you have fun.
If you found some bug, let me know.
Things I want do:
Transform the LUA files into one.
Optimize the loot message.
Add ModalWindow
Cheers~
Yo. I developed this system as a method of study. (C++). If u found some bug, report it here and I will fix that.
thanks for @Delusion for the help. This system have was inspired in Auto Loot System by @psychonaut.
This system was created in the latest version of tfs.
How it works?
Simple, when you kill some monster and open the corpse (you need click in corpse to loot), the items go for you character.
Installation
in actions.cpp, find:
C++:
if (corpseOwner != 0 && !player->canOpenCorpse(corpseOwner)) {
return RETURNVALUE_YOUARENOTTHEOWNER;
}
and change it for:
C++:
if (corpseOwner != 0 && !player->canOpenCorpse(corpseOwner)) {
return RETURNVALUE_YOUARENOTTHEOWNER;
} else {
if (player->canOpenCorpse(corpseOwner) && player->autoLootList.size() != 0) {
if (player->getCapacity() > 100 * 100) { //Minimum of Capacity for autoloot works. (100 CAP)
for (Item* item : container->getItemList()) {
if (player->getItemFromAutoLoot(item->getID())) {
std::ostringstream msgAutoLoot;
msgAutoLoot << "You looted a " << item->getItemCount() << "x " << item->getName() << ".";
g_game.internalMoveItem(container, player, CONST_SLOT_WHEREEVER, item, item->getItemCount(), nullptr);
player->sendTextMessage(MESSAGE_INFO_DESCR, msgAutoLoot.str());
}
}
} else {
player->sendTextMessage(MESSAGE_INFO_DESCR, "Sorry, you don't have enough capacity to use auto loot, so it has been disabled. (100+ capacity is required)");
}
}
}
in player.h, below
C++:
std::unordered_set<uint32_t> VIPList;
Add this
C++:
std::set<uint32_t> autoLootList;
below that:
C++:
bool hasLearnedInstantSpell(const std::string& spellName) const;
Add this
C++:
void addItemToAutoLoot(uint16_t itemId);
void removeItemFromAutoLoot(uint16_t itemId);
bool getItemFromAutoLoot(uint16_t itemId);
in player.cpp, in the end... add
C++:
void Player::addItemToAutoLoot(uint16_t itemId)
{
autoLootList.insert(itemId);
}
void Player::removeItemFromAutoLoot(uint16_t itemId)
{
autoLootList.erase(itemId);
}
bool Player::getItemFromAutoLoot(const uint16_t itemId)
{
return autoLootList.find(itemId) != autoLootList.end();
}
in luascript.cpp, find
C++:
registerMethod("Player", "getFightMode", LuaScriptInterface::luaPlayerGetFightMode);
add that below
C++:
registerMethod("Player", "addItemToAutoLoot", LuaScriptInterface::luaPlayerAddItemToAutoLoot);
registerMethod("Player", "removeItemFromAutoLoot", LuaScriptInterface::luaPlayerRemoveItemFromAutoLoot);
registerMethod("Player", "getItemFromAutoLoot", LuaScriptInterface::luaPlayerGetItemFromAutoLoot);
registerMethod("Player", "getAutoLootList", LuaScriptInterface::luaPlayerGetAutoLootList);
yet in luascript.cpp, find this function
C++:
int LuaScriptInterface::luaPlayerGetFightMode(lua_State* L)
{
// player:getFightMode()
Player* player = getUserdata<Player>(L, 1);
if (player) {
lua_pushnumber(L, player->fightMode);
} else {
lua_pushnil(L);
}
return 1;
}
below this whole function, add
C++:
int LuaScriptInterface::luaPlayerAddItemToAutoLoot(lua_State* L)
{
// player:addItemToAutoLoot(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->addItemToAutoLoot(itemId);
pushBoolean(L, true);
return 1;
}
int LuaScriptInterface::luaPlayerRemoveItemFromAutoLoot(lua_State* L)
{
// player:removeItemFromAutoLoot(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->removeItemFromAutoLoot(itemId);
pushBoolean(L, true);
return 1;
}
int LuaScriptInterface::luaPlayerGetItemFromAutoLoot(lua_State* L)
{
// player:getItemFromAutoLoot(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->getItemFromAutoLoot(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;
}
in luascript.h, find
C++:
static int luaPlayerGetFightMode(lua_State* L);
add below
C++:
static int luaPlayerAddItemToAutoLoot(lua_State* L);
static int luaPlayerRemoveItemFromAutoLoot(lua_State* L);
static int luaPlayerGetItemFromAutoLoot(lua_State* L);
static int luaPlayerGetAutoLootList(lua_State* L);
And in iologindata.cpp, below:
C++:
//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
C++:
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->addItemToAutoLoot(value);
item = propStreamList.read<int16_t>(value);
}
}
And above:
C++:
//save inbox items
add
C++:
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;
}
now, go to your database and execute this query:
Code:
CREATE TABLE player_autoloot (
id int NOT NULL AUTO_INCREMENT,
player_id int NOT NULL,
autoloot_list blob,
PRIMARY KEY (id)
);
go your data/scripts/talkactions and create this file:
autoloot.lua
Lua:
local talk = TalkAction("!autoloot")
function talk.onSay(player, words, param)
local i = player:getAutoLootList()
local cache = "Check your loot list: "
local split = param:split(",")
local action = split[1]
if param == "list" then
if i then
for _, item in ipairs(i) do
cache = cache .. (ItemType(item)):getName() .. ", "
end
else
player:sendTextMessage(MESSAGE_INFO_DESCR, "Your list is empty! Add some item and try again.")
return false
end
player:sendTextMessage(MESSAGE_INFO_DESCR, cache:sub(1, -3))
return false
end
if action == "add" then
local item = split[2]:gsub("%s+", "", 1)
local itemType = ItemType(item)
if itemType:getId() == 0 then
itemType = ItemType(tonumber(item))
if itemType:getName() == '' then
player:sendCancelMessage("There is no item with that id or name.")
return false
end
end
if player:getItemFromAutoLoot(itemType:getId()) then
player:sendCancelMessage("You're already autolooting this item.")
return false
end
player:addItemToAutoLoot(itemType:getId())
player:sendTextMessage(MESSAGE_INFO_DESCR, "You're now auto looting " .. itemType:getName())
return false
elseif action == "remove" then
local item = split[2]:gsub("%s+", "", 1)
local itemType = ItemType(item)
if itemType:getId() == 0 then
itemType = ItemType(tonumber(item))
if itemType:getName() == '' then
player:sendCancelMessage("There is no item with that id or name.")
return false
end
end
if player:getItemFromAutoLoot(itemType:getId()) then
player:removeItemFromAutoLoot(itemType:getId())
player:sendTextMessage(MESSAGE_INFO_DESCR, "You removed the " .. itemType:getName() .. " from your loot list.")
else
player:sendCancelMessage("This item does not exist in your loot list.")
end
return false
end
player:sendTextMessage(MESSAGE_EVENT_ORANGE, "Auto Loot commands (items are automatically moved to your bp if you open monster corpse):"..'\n'.."!addloot add, nameItem - add item to auto loot by name"..'\n'.."!autoloot remove, itemName - remove item from auto loot by name"..'\n'.."!autoloot list - list your current auto loot items")
return false
end
talk:separator(" ")
talk:register()
That's it, I hope you have fun.
If you found some bug, let me know.
Things I want do:
Transform the LUA files into one.
Optimize the loot message.
Add ModalWindow
Cheers~
Attachments
-
commands.png94.1 KB · Views: 305 · VirusTotal
-
autoloot.png83.1 KB · Views: 186 · VirusTotal
Last edited: