E
Evil Puncker
Guest
I'm using this code for autoloot (not the onUse part), applied on latest TFS with several changes, it is working 99% fine, every function except the part where it should add the item to the selected container, it is adding everything into the main backpack only:
and I can't even think where to search for it in order to "try" fixing, so here I am asking you guys for help once again, the C++ part is the same as the link above, and for the rest, here they are:
events/script/monster.lua
lib/core/container.lua (I think this one is responsible for adding the item?)
OnModalWindow event:
OnStartup event:
functions that were needed and I don't have any idea why lol:
talkaction to add items to list and chose loot backpack:
As I said, everything is working 99% except the loot destination (bp_id I guess), the item is always going to the main backpack (CONST_SLOT_BACKPACK) no matter what
and I can't even think where to search for it in order to "try" fixing, so here I am asking you guys for help once again, the C++ part is the same as the link above, and for the rest, here they are:
events/script/monster.lua
Lua:
function Monster:onDropLoot(corpse)
if configManager.getNumber(configKeys.RATE_LOOT) == 0 then
return
end
local player = Player(corpse:getCorpseOwner())
local autolooted = ""
local mType = self:getType()
if not player or player:getStamina() > 840 then
local monsterLoot = mType:getLoot()
for i = 1, #monsterLoot do
local item = corpse:createLootItem(monsterLoot[i])
if not item then
print('[Warning] DropLoot:', 'Could not add loot item to corpse.')
end
-- autoloot
if item > 0 then
local tmpItem = Item(item)
if player and player:getAutoLootItem(tmpItem:getId()) then
if tmpItem:moveTo(player) then
autolooted = string.format("%s, %s", autolooted, tmpItem:getNameDescription())
end
end
end
end
if player then
local text = ("Loot of %s: "):format(mType:getNameDescription())
-- autoloot
local lootMsg = corpse:getContentDescription()
if autolooted ~= "" and corpse:getContentDescription() == "nothing" then
lootMsg = autolooted:gsub(",", "", 1) .. " that was autolooted"
elseif autolooted ~= "" then
lootMsg = corpse:getContentDescription() .. " and " .. autolooted:gsub(",", "", 1) .. " that was autolooted"
end
text = string.format("%s%s", text, lootMsg)
local party = player:getParty()
if party then
if autolooted ~= "" then
text = string.format("%s by %s", text, player:getName())
end
party:broadcastPartyLoot(text)
else
player:sendTextMessage(MESSAGE_LOOT, text)
end
end
else
local text = ("Loot of %s: nothing (due to low stamina)"):format(mType:getNameDescription())
local party = player:getParty()
if party then
party:broadcastPartyLoot(text)
else
player:sendTextMessage(MESSAGE_LOOT, text)
end
end
end
lib/core/container.lua (I think this one is responsible for adding the item?)
Lua:
function Container.createLootItem(self, item)
if self:getEmptySlots() == 0 then
return true
end
local itemCount = 0
local randvalue = getLootRandom()
if randvalue < item.chance then
if ItemType(item.itemId):isStackable() then
itemCount = randvalue % item.maxCount + 1
else
itemCount = 1
end
end
--if itemCount > 0 then
local tmpItem = false
if itemCount > 0 then
tmpItem = self:addItem(item.itemId, math.min(itemCount, 100))
--local tmpItem = self:addItem(item.itemId, math.min(itemCount, 100))
if not tmpItem then
return -1
--return false
end
if tmpItem:isContainer() then
for i = 1, #item.childLoot do
if not tmpItem:createLootItem(item.childLoot[i]) then
tmpItem:remove()
return -1
--return false
end
end
end
if item.subType ~= -1 then
tmpItem:setAttribute(ITEM_ATTRIBUTE_CHARGES, item.subType)
end
if item.actionId ~= -1 then
tmpItem:setActionId(item.actionId)
end
if item.text and item.text ~= "" then
tmpItem:setText(item.text)
end
end
--return true
return tmpItem and tmpItem.uid or 0
end
OnModalWindow event:
Lua:
function call(player, param, param2, tobpid)
player:registerEvent('autoloot')
local title = "Autoloot Helper!"
if param == 'add' then
local lootBlockList = lootBlockListm[player:getGuid()]
local message = "Loot of "..string.gsub(" "..string.lower(lootBlockListn[player:getGuid()]), "%W%l", string.upper):sub(2)..":"
local window = ModalWindow(1001, title, message)
local check, sum = {}, 1
for _, loot in pairs(lootBlockList) do
local status = ''
if player:getAutoLootItem(lootBlockList[sum].itemId) then
status = '*'
end
if not table.contains(check, ItemType(lootBlockList[sum].itemId):getName()) then
table.insert(check, ItemType(lootBlockList[sum].itemId):getName())
local resultId = db.storeQuery('SELECT `cont_id` FROM `player_autoloot_persist` WHERE `player_guid` = ' .. player:getGuid() .. ' AND `item_id` = ' .. lootBlockList[sum].itemId .. '')
if resultId then
local bp_id = result.getNumber(resultId, 'cont_id')
end
local backvinculo
if result.getNumber(resultId, 'cont_id') and result.getNumber(resultId, 'cont_id') > 0 then
backvinculo = '( '..ItemType(result.getNumber(resultId, 'cont_id')):getName()..''
else
backvinculo = ''
end
window:addChoice(sum, "".. string.gsub(" "..status..""..ItemType(lootBlockList[sum].itemId):getName(), "%W%l", string.upper):sub(2, 21) .." ( "..lootBlockList[sum].maxCount.." ) "..(lootBlockList[sum].chance/1000).."% "..string.gsub(" "..string.lower(backvinculo), "%W%l", string.upper):sub(2).."")
end
sum = sum + 1
end
if autolootBP == 1 then
window:addButton(105, "Backpack")
end
callwindow(window, player, 1)
elseif param == 'remove' then
local message = "You are currently looting the following items:"
local window = ModalWindow(1000, title, message)
local check, sum = player:getAutoLootList(), 1
if check then
table.sort(check, function(a, b) return ItemType(a):getName() < ItemType(b):getName() end)
for _, item in ipairs(check) do
local resultId = db.storeQuery('SELECT `cont_id` FROM `player_autoloot_persist` WHERE `player_guid` = ' .. player:getGuid() .. ' AND `item_id` = ' .. ItemType(check[sum]):getId() .. '')
if resultId then
local bp_id = result.getNumber(resultId, 'cont_id')
end
local backvinculo
if result.getNumber(resultId, 'cont_id') and result.getNumber(resultId, 'cont_id') > 0 then
backvinculo = '( '..ItemType(result.getNumber(resultId, 'cont_id')):getName()..''
else
backvinculo = ''
end
window:addChoice(sum, "".. string.gsub(" "..(ItemType(item)):getName(), "%W%l", string.upper):sub(2, 21) .." "..string.gsub(" "..string.lower(backvinculo), "%W%l", string.upper):sub(2).."")
sum = sum + 1
end
else
player:sendCancelMessage("The list is empty.")
return false
end
if autolootBP == 1 then
window:addButton(106, "Backpack")
end
callwindow(window, player, 2)
elseif param == 'backpack' then
local lootBlockList = lootBlockListm[player:getGuid()]
local modalcode
if param2 and param2 == 1001 then
modalcode = 1005
else
modalcode = 1006
end
local message = "Choose a Backpack:"
local container2 = player:getSlotItem(CONST_SLOT_BACKPACK)
local window = ModalWindow(modalcode, title, message)
local sum = 1
local container, names = {}, {}
if container2:getSize() then
for i = 0, container2:getSize() - 1 do
local thing = container2:getItem(i)
container[i] = container2:getItem(i)
if container[i]:isContainer() then
if not table.contains(names, container[i].itemId) then
table.insert(names, container[i].itemId)
window:addChoice(sum, ""..string.gsub(" "..string.lower(ItemType(container[i].itemid):getName()), "%W%l", string.upper):sub(2).."")
end
sum = sum + 1
end
end
else
player:sendCancelMessage("Main backpack not found.")
return false
end
if sum == 1 then
player:sendCancelMessage("Sub-backpack not found.")
return false
end
callwindow(window, player, 3)
end
end
function callwindow(window, player, param)
if param == 3 then
window:setDefaultEnterButton(100, "Confirm")
window:addButton(100, "Confirm")
else
window:addButton(100, "Confirm")
window:addButton(102, "Remove")
window:setDefaultEnterButton(106, "Backpack")
if param == 1 then
window:addButton(103, "Add")
window:setDefaultEnterButton(103, "Add")
window:addButton(105, "Backpack")
end
end
window:sendToPlayer(player)
end
local creatureevent = CreatureEvent("autoloot")
function creatureevent.onModalWindow(player, modalWindowId, buttonId, choiceId)
player:unregisterEvent('autoloot')
local limiteAutoloot = 100
local autolootlist, sum = {}, 1
if buttonId == 102 and modalWindowId == 1000 then
local playerlist = player:getAutoLootList()
if playerlist then
table.sort(playerlist, function(a, b) return ItemType(a):getName() < ItemType(b):getName() end)
for _, item in ipairs(playerlist) do
table.insert(autolootlist, "".. item .."")
end
local itemType = ItemType(tonumber(autolootlist[choiceId]))
player:sendTextMessage(MESSAGE_INFO_DESCR,'Removed '.. string.gsub(" "..ItemType(tonumber(autolootlist[choiceId])):getName(), "%W%l", string.upper):sub(2, 21)..' from autoloot list!')
db.query('DELETE FROM `player_autoloot_persist` WHERE `player_guid` = ' .. player:getGuid() .. ' AND `item_id` = ' .. itemType:getId() .. '')
player:removeAutoLootItem(itemType:getId())
call(player, 'remove')
end
elseif buttonId == 102 and modalWindowId == 1001 or buttonId == 103 then
local lootBlockList = lootBlockListm[player:getGuid()]
if lootBlockList == nil or lootBlockList == -1 then
return false
end
for _, loot in pairs(lootBlockList) do
table.insert(autolootlist, lootBlockList[sum].itemId)
sum = sum + 1
end
local itemType = ItemType(tonumber(autolootlist[choiceId]))
if buttonId == 102 then
player:sendTextMessage(MESSAGE_INFO_DESCR,'Removed '.. string.gsub(" "..ItemType(itemType:getId()):getName(), "%W%l", string.upper):sub(2, 21)..' from autoloot list!')
db.query('DELETE FROM `player_autoloot_persist` WHERE `player_guid` = ' .. player:getGuid() .. ' AND `item_id` = ' .. itemType:getId() .. '')
player:removeAutoLootItem(itemType:getId())
elseif buttonId == 103 then
if player:getAutoLootList() then
local playerlist = player:getAutoLootList()
end
if playerlist then
for _, item in ipairs(playerlist) do
table.insert(autolootlist, "".. item .."")
end
end
if playerlist and #playerlist >= limiteAutoloot then
player:sendCancelMessage("Reached the limit <"..#playerlist.."> for itens, first remove using !autoloot or !add <monster>, selecting option remove.")
return false
else
player:sendTextMessage(MESSAGE_INFO_DESCR,'Add '.. string.gsub(" "..ItemType(lootBlockList[choiceId].itemId):getName(), "%W%l", string.upper):sub(2, 21) ..' to autoloot list!')
player:addAutoLootItem(itemType:getId())
end
end
call(player, 'add')
elseif buttonId == 105 then
local lootBlockList = lootBlockListm[player:getGuid()]
if lootBlockList == nil or lootBlockList == -1 then
return false
end
for _, loot in pairs(lootBlockList) do
table.insert(autolootlist, lootBlockList[sum].itemId)
sum = sum + 1
end
local itemType = ItemType(tonumber(autolootlist[choiceId]))
lastitem[player:getGuid()] = lootBlockList[choiceId].itemId
call(player, 'backpack', modalWindowId, lastitem[player:getGuid()])
elseif buttonId == 106 then
local lootBlockList = player:getAutoLootList()
table.sort(lootBlockList, function(a, b) return ItemType(a):getName() < ItemType(b):getName() end)
if lootBlockList == nil or lootBlockList == -1 then
return false
end
for _, loot in pairs(lootBlockList) do
table.insert(autolootlist, lootBlockList[sum])
sum = sum + 1
end
local itemType = ItemType(tonumber(autolootlist[choiceId]))
lastitem[player:getGuid()] = lootBlockList[choiceId]
call(player, 'backpack', modalWindowId, lastitem[player:getGuid()])
elseif buttonId == 100 then
if modalWindowId == 1005 then
local container, bp, sequencer = {}, {}, 1
local container2 = player:getSlotItem(CONST_SLOT_BACKPACK)
local bp2 = {}
for i = 0, container2:getSize() - 1 do
local thing = container2:getItem(i)
container[i] = container2:getItem(i)
if container[i]:isContainer() then
container[i] = Item(container[i].uid)
bp[sequencer] = container[i]
bp2[sequencer] = container[i]:getId()
sequencer = sequencer + 1
end
end
if sequencer > 1 then
if player:getAutoLootItem(lastitem[player:getGuid()]) then
local resultId = db.storeQuery('SELECT `cont_id` FROM `player_autoloot_persist` WHERE `player_guid` = ' .. player:getGuid() .. ' AND `item_id` = ' .. lastitem[player:getGuid()] .. '')
if resultId then
local bp_id = result.getNumber(resultId, 'cont_id')
else
db.query("INSERT INTO `player_autoloot_persist` (`player_guid`, `cont_id`, `item_id`) VALUES (".. player:getGuid() ..", ".. bp2[choiceId] ..", ".. lastitem[player:getGuid()] ..") ON DUPLICATE KEY UPDATE `cont_id` = ".. bp2[choiceId])
end
if result.getNumber(resultId, 'cont_id') and result.getNumber(resultId, 'cont_id') ~= bp2[choiceId] then
db.query('UPDATE `player_autoloot_persist` SET `cont_id` = '..bp2[choiceId]..' WHERE `player_guid` = ' .. player:getGuid() .. ' AND `item_id` = ' .. lastitem[player:getGuid()] .. '')
end
end
end
call(player, 'add')
end
if modalWindowId == 1006 then
local container, bp, sequencer = {}, {}, 1
local container2 = player:getSlotItem(CONST_SLOT_BACKPACK)
local bp2 = {}
for i = 0, container2:getSize() - 1 do
local thing = container2:getItem(i)
container[i] = container2:getItem(i)
if container[i]:isContainer() then
container[i] = Item(container[i].uid)
bp[sequencer] = container[i]
bp2[sequencer] = container[i]:getId()
sequencer = sequencer + 1
end
end
if sequencer > 1 then
local resultId = db.storeQuery('SELECT `cont_id` FROM `player_autoloot_persist` WHERE `player_guid` = ' .. player:getGuid() .. ' AND `item_id` = ' .. lastitem[player:getGuid()] .. '')
if resultId then
local bp_id = result.getNumber(resultId, 'cont_id')
else
db.query("INSERT INTO `player_autoloot_persist` (`player_guid`, `cont_id`, `item_id`) VALUES (".. player:getGuid() ..", ".. bp2[choiceId] ..", ".. lastitem[player:getGuid()] ..") ON DUPLICATE KEY UPDATE `cont_id` = ".. bp2[choiceId])
end
if result.getNumber(resultId, 'cont_id') and result.getNumber(resultId, 'cont_id') ~= bp2[choiceId] then
db.query('UPDATE `player_autoloot_persist` SET `cont_id` = '..bp2[choiceId]..' WHERE `player_guid` = ' .. player:getGuid() .. ' AND `item_id` = ' .. lastitem[player:getGuid()] .. '')
end
end
call(player, 'remove')
end
end
end
creatureevent:register()
OnStartup event:
Lua:
local globalevent = GlobalEvent("autoloot")
function globalevent.onStartup()
lootBlockListm = {}
lootBlockListn = {}
lastitem = {}
autolootBP = 1 -- 0 = disable, 1 = enable (only works with autolootmode = 2)
return true
end
globalevent:register()
functions that were needed and I don't have any idea why lol:
Lua:
local function pushValues(buffer, sep, ...)
local argv = {...}
local argc = #argv
for k, v in ipairs(argv) do
table.insert(buffer, v)
if k < argc and sep then
table.insert(buffer, sep)
end
end
end
function Item.getNameDescription(self)
local subType = self:getSubType()
local itemType = self:getType()
local buffer = {}
local name = self:getName() or ''
if(#name ~= 0) then
if(itemType:isStackable() and subType > 1) then
pushValues(buffer, ' ', subType, self:getPluralName())
else
local article = self:getArticle() or ''
pushValues(buffer, ' ', select(#article ~= 0 and 1 or 2, article, name))
end
else
pushValues(buffer, ' ', 'an item of type', self:getId())
end
return table.concat(buffer)
end
talkaction to add items to list and chose loot backpack:
Lua:
local talk = TalkAction("!add")
function talk.onSay(player, words, param)
local monsterType = MonsterType(param)
if not monsterType then
player:sendCancelMessage("Can't find monster.")
return false
end
player:registerEvent('autoloot')
local title = "Autoloot Helper!"
local message = "Loot of "..string.gsub(" "..string.lower(param), "%W%l", string.upper):sub(2)..":"
local lootBlockList = monsterType:getLoot()
table.sort(lootBlockList, function(a, b) return ItemType(a.itemId):getName() < ItemType(b.itemId):getName() end)
lootBlockListm[player:getGuid()] = lootBlockList
lootBlockListn[player:getGuid()] = param
local window = ModalWindow(1001, title, message)
local check, sum = {}, 1
for _, loot in pairs(lootBlockList) do
local status = ''
if player:getAutoLootItem(lootBlockList[sum].itemId) then
status = '*'
end
if not table.contains(check, ItemType(lootBlockList[sum].itemId):getName()) then
table.insert(check, ItemType(lootBlockList[sum].itemId):getName())
local resultId = db.storeQuery('SELECT `cont_id` FROM `player_autoloot_persist` WHERE `player_guid` = ' .. player:getGuid() .. ' AND `item_id` = ' .. lootBlockList[sum].itemId .. '')
if resultId then
local bp_id = result.getNumber(resultId, 'cont_id')
end
local backvinculo
if result.getNumber(resultId, 'cont_id') and result.getNumber(resultId, 'cont_id') > 0 then
backvinculo = '| '..ItemType(result.getNumber(resultId, 'cont_id')):getName()..''
else
backvinculo = ''
end
window:addChoice(sum, "".. string.gsub(" "..status..""..ItemType(lootBlockList[sum].itemId):getName(), "%W%l", string.upper):sub(2, 21) .." | "..lootBlockList[sum].maxCount.." | "..(lootBlockList[sum].chance/1000).."% "..string.gsub(" "..string.lower(backvinculo), "%W%l", string.upper):sub(2).."")
end
sum = sum + 1
end
window:addButton(105, "Backpack")
window:setDefaultEnterButton(103, "Add")
window:addButton(100, "Confirm")
if autolootBP == 1 then
window:addButton(102, "Remove")
end
window:addButton(103, "Add")
window:sendToPlayer(player)
return false
end
talk:separator(" ")
talk:register()
As I said, everything is working 99% except the loot destination (bp_id I guess), the item is always going to the main backpack (CONST_SLOT_BACKPACK) no matter what
Last edited by a moderator: