Skip to content

Commit

Permalink
[Feature] Auto Loot
Browse files Browse the repository at this point in the history
  • Loading branch information
roddett committed Feb 1, 2023
1 parent a0a2c46 commit 959152b
Show file tree
Hide file tree
Showing 14 changed files with 585 additions and 3 deletions.
5 changes: 5 additions & 0 deletions config.lua
Expand Up @@ -320,6 +320,11 @@
vipListDefaultLimit = 20
vipListDefaultPremiumLimit = 100

-- AutoLoot
useAutoLoot = true
-- # set 0 to disable message
autoLootMessageType = 24

-- Outfits
allowChangeOutfit = true
allowChangeColors = true
Expand Down
4 changes: 4 additions & 0 deletions data/lib/000-constant.lua
Expand Up @@ -7,6 +7,10 @@ SOUTHEAST = 5
NORTHWEST = 6
NORTHEAST = 7

AUTOLOOT_STATUS = 1
AUTOLOOT_GOLD = 2
AUTOLOOT_BANK = 3

--TFS 0.3.6/0.4 COMPATIBILITY
doors = {[1209] = 1211, [1210] = 1211, [1212] = 1214, [1213] = 1214, [1219] = 1220, [1221] = 1222, [1231] = 1233, [1232] = 1233, [1234] = 1236, [1235] = 1236, [1237] = 1238, [1239] = 1240, [1249] = 1251, [1250] = 1251, [1252] = 1254, [1253] = 1254, [1539] = 1540, [1541] = 1542, [3535] = 3537, [3536] = 3537, [3538] = 3539, [3544] = 3546, [3545] = 3546, [3547] = 3548, [4913] = 4915, [4914] = 4915, [4916] = 4918, [4917] = 4918, [5082] = 5083, [5084] = 5085, [5098] = 5100, [5099] = 5100, [5101] = 5102, [5107] = 5109, [5108] = 5109, [5110] = 5111, [5116] = 5118, [5117] = 5118, [5119] = 5120, [5125] = 5127, [5126] = 5127, [5128] = 5129, [5134] = 5136, [5135] = 5136, [5137] = 5139, [5138] = 5139, [5140] = 5142, [5141] = 5142, [5143] = 5145, [5144] = 5145, [5278] = 5280, [5279] = 5280, [5281] = 5283, [5282] = 5283, [5284] = 5285, [5286] = 5287, [5515] = 5516, [5517] = 5518, [5732] = 5734, [5733] = 5734, [5735] = 5737, [5736] = 5737, [6192] = 6194, [6193] = 6194, [6195] = 6197, [6196] = 6197, [6198] = 6199, [6200] = 6201, [6249] = 6251, [6250] = 6251, [6252] = 6254, [6253] = 6254, [6255] = 6256, [6257] = 6258, [6795] = 6796, [6797] = 6798, [6799] = 6800, [6801] = 6802, [6891] = 6893, [6892] = 6893, [6894] = 6895, [6900] = 6902, [6901] = 6902, [6903] = 6904, [7033] = 7035, [7034] = 7035, [7036] = 7037, [7042] = 7044, [7043] = 7044, [7045] = 7046, [7054] = 7055, [7056] = 7057, [8541] = 8543, [8542] = 8543, [8544] = 8546, [8545] = 8546, [8547] = 8548, [8549] = 8550, [9165] = 9167, [9166] = 9167, [9168] = 9170, [9169] = 9170, [9171] = 9172, [9173] = 9174, [9267] = 9269, [9268] = 9269, [9270] = 9272, [9271] = 9272, [9273] = 9274, [9275] = 9276, [10276] = 10277, [10274] = 10275, [10268] = 10270, [10269] = 10270, [10271] = 10273, [10272] = 10273, [10471] = 10472, [10480] = 10481, [10477] = 10479, [10478] = 10479, [10468] = 10470, [10469] = 10470, [10774] = 10776, [10775] = 10776, [10779] = 10780, [10781] = 10782, [10783] = 10785, [10784] = 10785, [10788] = 10789, [10790] = 10791}
closingDoors = {1224, 1226, 1228, 1230, 1242, 1244, 1246, 1248, 1256, 1258, 1260, 1262, 3541, 3543, 3550, 3552, 5104, 5106, 5113, 5115, 5122, 5124, 5131, 5133, 5289, 5291, 5293, 5295, 6203, 6205, 6207, 6209, 6260, 6262, 6264, 6266, 6897, 6899, 6906, 6908, 7039, 7041, 7048, 7050, 8552, 8554, 8556, 8558, 9176, 9178, 9180, 9182, 9278, 9280, 9282, 9284, 10279, 10281, 10283, 10285, 10474, 10476, 10483, 10485, 10780, 10782, 10789, 10791}
Expand Down
188 changes: 188 additions & 0 deletions data/talkactions/scripts/autoloot.lua
@@ -0,0 +1,188 @@
-- Column -> ALTER TABLE `players` ADD autoloot BLOB NOT NULL AFTER `conditions`;
-- Clean Settings -> UPDATE `players` SET `autoloot` = "";

local autoLoot = {}
autoLoot.blockedIds = {}
autoLoot.maxSlots = 5 -- # if you set a lower value than the previous one, you should clean the autoloot settings to reset the players item slots

local isValidItem = function(itemId)
local it = getItemInfo(itemId)
return (
it.movable and
it.pickupable and
it.worth == 0 and
it.corpseType == 0
)
end

local getInputItem = function(typeInput)

local itemId = tonumber(typeInput) or (getItemIdByName(typeInput) or 0)
local itemType = getItemInfo(itemId)

if not itemType then
return false
end

return itemId
end

local useSystem = getBooleanFromString(getConfigValue('useAutoLoot'))
function onSay(cid, words, param, channel)

if not useSystem then
return false
end

if not checkExhausted(cid, 666, 10) then
return true
end

param = param:lower()
params = param:explode(",")

-- ###### Miscellaneous Commands ##### --
if (param == "on") then
if getAutoLootSetting(cid, AUTOLOOT_STATUS) then
return doPlayerSendCancel(cid, "Your autoloot is currently active.")
end

doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "[Auto-Loot]: You have enabled the autoloot feature.")
return setAutoLootSetting(cid, AUTOLOOT_STATUS, 1)
end

if (param == "off") then
if not getAutoLootSetting(cid, AUTOLOOT_STATUS) then
return doPlayerSendCancel(cid, "Your autoloot is currently disable.")
end

doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_RED, "[Auto-Loot]: You have disabled the autoloot feature.")
return setAutoLootSetting(cid, AUTOLOOT_STATUS, 0)
end

if (params[1] == "gold" or params[1] == "money") then

if params[2] == "on" then
if getAutoLootSetting(cid, AUTOLOOT_GOLD) then
return doPlayerSendCancel(cid, "Your autoloot is currently colleting gold.")
end

doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "[Auto-Loot]: You autoloot is now collecting gold coins.")
return setAutoLootSetting(cid, AUTOLOOT_GOLD, 1)
end

if params[2] == "off" then
if not getAutoLootSetting(cid, AUTOLOOT_GOLD) then
return doPlayerSendCancel(cid, "Your autoloot is not colleting gold.")
end

doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_RED, "[Auto-Loot]: Your autoloot is not collecting gold coins anymore.")
return setAutoLootSetting(cid, AUTOLOOT_GOLD, 0)
end
end

if (params[1] == "bank" or params[1] == "transfer") then
if params[2] == "on" then
if getAutoLootSetting(cid, AUTOLOOT_BANK) then
return doPlayerSendCancel(cid, "Your autoloot is currently sending gold coins to your bank account.")
end

doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "[Auto-Loot]: Your autoloot now will send the gold coins to your bank account.")
return setAutoLootSetting(cid, AUTOLOOT_BANK, 1)
end

if params[2] == "off" then
if not getAutoLootSetting(cid, AUTOLOOT_BANK) then
return doPlayerSendCancel(cid, "Your autoloot is not sending gold coins to your bank account.")
end

doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_RED, "[Auto-Loot]: Your autoloot will no longer send the gold coins to your bank account.")
return setAutoLootSetting(cid, AUTOLOOT_BANK, 0)
end
end

-- ###### List Commands ##### --
local currentLootList = getAutoLootList(cid)
if (params[1] == "add") then

local itemId = params[2]
if not itemId then
return doPlayerSendCancel(cid, "Please input the item id or name.")
end

itemId = getInputItem(itemId)
if not itemId then
return doPlayerSendCancel(cid, "This item does not exists.")
end

if not isValidItem(itemId) then
return doPlayerSendCancel(cid, "This item is not valid, please add another one.")
end

if isInArray(autoLoot.blockedIds, itemId) then
return doPlayerSendCancel(cid, "This item cannot be added to the list.")
end

if getAutoLootItemId(cid, itemId) then
return doPlayerSendCancel(cid, "You already have this item on your list.")
end

if #currentLootList >= autoLoot.maxSlots then
return doPlayerSendCancel(cid, "You cannot add more items to your list.")
end

doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "[Auto-Loot]: You have added -> " .. getItemNameById(itemId) .. " <- to your list.")
return setAutoLootItemId(cid, itemId)
end

if (params[1] == "remove") then

local itemId = params[2]
if not itemId then
return doPlayerSendCancel(cid, "Please input the item id or name.")
end

itemId = (getInputItem(itemId) or 0)
if not getAutoLootItemId(cid, itemId) then
return doPlayerSendCancel(cid, "This item is not on your list.")
end

doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_RED, "[Auto-Loot]: You have removed -> " .. getItemNameById(itemId) .. " <- from your list.")
return eraseAutoLootItemId(cid, itemId)
end

if (params[1] == "list") then

local outputList = {}
for i = 1, math.max(autoLoot.maxSlots, #currentLootList) do
outputList[#outputList + 1] = "Item Slot [" .. i .. "] -> " .. (currentLootList[i] and getItemNameById(currentLootList[i]) or "empty")
end

return doPlayerPopupFYI(cid, "[+] AutoLoot List [+] \n\n" .. table.concat(outputList, "\n"))
end

if (params[1] == "clear") then

if #currentLootList <= 0 then
return doPlayerSendCancel(cid, "Your autoloot list is currently empty.")
end

doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "[Auto-Loot]: Your item list has been reseted.")
return clearAutoLootList(cid)
end

return doPlayerPopupFYI(cid, table.concat({
"[+] AutoLoot Commands [+]", "", -- # new line
"!autoloot [on / off]",
"!autoloot add, item",
"!autoloot remove, item",
"!autoloot list",
"!autoloot clear", "",
"Status: " .. (getAutoLootSetting(cid, AUTOLOOT_STATUS) and "active" or "disable"), "",
"[+] Gold Commands [+]", "",
"!autoloot gold, [on / off]",
"!autoloot transfer, [on / off]", "",
"Status: " .. (getAutoLootSetting(cid, AUTOLOOT_GOLD) and "active" or "disable"),
"Bank Transfer: " .. (getAutoLootSetting(cid, AUTOLOOT_BANK) and "yes" or "no")
}, "\n"))
end
1 change: 1 addition & 0 deletions data/talkactions/talkactions.xml
Expand Up @@ -40,6 +40,7 @@
<talkaction log="yes" group="4" access="3" words="/baninfo" event="function" value="banishmentInfo"/>

<!-- Players -->
<talkaction access="0-4" words="!autoloot" event="script" value="autoloot.lua"/>
<talkaction access="0-4" words="!frags;/frags" event="script" value="frags.lua"/>
<talkaction access="0-4" words="!online;/online" event="script" value="online.lua"/>
<talkaction access="0-4" words="!uptime;/uptime" event="script" value="uptime.lua"/>
Expand Down
2 changes: 2 additions & 0 deletions sources/configmanager.cpp
Expand Up @@ -362,6 +362,8 @@ bool ConfigManager::load()
m_confBool[ALLOW_CORPSE_BLOCK] = getGlobalBool("allowCorpseBlock", false);
m_confBool[ALLOW_INDEPENDENT_PUSH] = getGlobalBool("allowIndependentCreaturePush", true);
m_confBool[PZLOCK_ON_ATTACK_SKULLED_PLAYERS] = getGlobalBool("pzlockOnAttackSkulledPlayers", false);
m_confNumber[AUTOLOOT_MESSAGE_TYPE] = getGlobalNumber("autoLootMessageType", 24);
m_confBool[USE_AUTOLOOT] = getGlobalBool("useAutoLoot", false);
m_loaded = true;
return true;
}
Expand Down
2 changes: 2 additions & 0 deletions sources/configmanager.h
Expand Up @@ -196,6 +196,7 @@ class ConfigManager
HIGHSCORES_TOP,
HIGHSCORES_UPDATETIME,
LOGIN_PROTECTION_TIME,
AUTOLOOT_MESSAGE_TYPE,
LAST_NUMBER_CONFIG /* this must be the last one */
};

Expand Down Expand Up @@ -331,6 +332,7 @@ class ConfigManager
ALLOW_CORPSE_BLOCK,
ALLOW_INDEPENDENT_PUSH,
PZLOCK_ON_ATTACK_SKULLED_PLAYERS,
USE_AUTOLOOT,
LAST_BOOL_CONFIG /* this must be the last one */
};

Expand Down
7 changes: 7 additions & 0 deletions sources/creature.cpp
Expand Up @@ -816,6 +816,13 @@ void Creature::dropCorpse(DeathList deathList)

g_game.internalAddItem(NULL, tile, corpse, INDEX_WHEREEVER, FLAG_NOLIMIT);
dropLoot(corpse->getContainer());

if (g_config.getBool(ConfigManager::USE_AUTOLOOT))
{
if (Monster* monster = getMonster())
monster->executeAutoLoot(corpse->getContainer(), deathList);
}

g_game.startDecay(corpse);
}

Expand Down
46 changes: 45 additions & 1 deletion sources/iologindata.cpp
Expand Up @@ -423,7 +423,7 @@ bool IOLoginData::loadPlayer(Player* player, const std::string& name, bool preLo
query << "SELECT `id`, `account_id`, `group_id`, `world_id`, `sex`, `vocation`, `experience`, `level`, "
<< "`maglevel`, `health`, `healthmax`, `blessings`, `pvp_blessing`, `mana`, `manamax`, `manaspent`, `soul`, "
<< "`lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`, `lookaddons`, `posx`, `posy`, "
<< "`posz`, `cap`, `lastlogin`, `lastlogout`, `lastip`, `conditions`, `skull`, `skulltime`, `guildnick`, "
<< "`posz`, `cap`, `lastlogin`, `lastlogout`, `lastip`, `conditions`, `autoloot`, `skull`, `skulltime`, `guildnick`, "
<< "`rank_id`, `town_id`, `balance`, `stamina`, `direction`, `loss_experience`, `loss_mana`, `loss_skills`, "
<< "`loss_containers`, `loss_items`, `marriage`, `promotion`, `description`, `offlinetraining_time`, `offlinetraining_skill`, "
<< "`save` FROM `players` WHERE "
Expand Down Expand Up @@ -509,6 +509,32 @@ bool IOLoginData::loadPlayer(Player* player, const std::string& name, bool preLo
delete condition;
}

uint64_t autoLootSize = 0;
const char* autoLootList = result->getDataStream("autoloot", autoLootSize);

propStream.init(autoLootList, autoLootSize);

int32_t i = 0;
uint8_t byte = 0;

while (propStream.getByte(byte))
{
int32_t type = byte;
if (type == AUTOLOOT_ITEM)
{
uint32_t itemId;
if (propStream.getLong(itemId))
player->setAutoLootItemId(itemId);
}

if (type == AUTOLOOT_SETTING)
{
uint16_t value;
if (propStream.getShort(value))
player->autoLootSettings[i++] = value;
}
}

player->vocationId = result->getDataInt("vocation");
player->setPromotionLevel(result->getDataInt("promotion"));

Expand Down Expand Up @@ -949,6 +975,24 @@ bool IOLoginData::savePlayer(Player* player, bool preSave/* = true*/, bool shall
const char* conditions = propWriteStream.getStream(conditionsSize);
query << "`conditions` = " << db->escapeBlob(conditions, conditionsSize) << ", ";

//serialize autoloot
propWriteStream.clear();
for (AutoLootSet::const_iterator it = player->getAutoLootList().begin(); it != player->getAutoLootList().end(); ++it)
{
propWriteStream.addByte(AUTOLOOT_ITEM);
propWriteStream.addLong(*it);
}

for (uint16_t value : player->autoLootSettings)
{
propWriteStream.addByte(AUTOLOOT_SETTING);
propWriteStream.addShort(value);
}

uint32_t autoLootSize = 0;
const char* autoLoot = propWriteStream.getStream(autoLootSize);
query << "`autoloot` = " << db->escapeBlob(autoLoot, autoLootSize) << ", ";

query << "`loss_experience` = " << (uint32_t)player->getLossPercent(LOSS_EXPERIENCE) << ", ";
query << "`loss_mana` = " << (uint32_t)player->getLossPercent(LOSS_MANA) << ", ";
query << "`loss_skills` = " << (uint32_t)player->getLossPercent(LOSS_SKILLS) << ", ";
Expand Down

0 comments on commit 959152b

Please sign in to comment.