• 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.X+ block or delete certain items from monsters loot

beenii

Well-Known Member
Joined
Jul 26, 2010
Messages
586
Solutions
1
Reaction score
58
Hello, does anyone have any idea how to remove certain items from the loot that the monsters give?
An example, I want leather set to be obtained in Quests.

Leather Helmet, Leather Armor, Leather Legs, Leather Boots
as we all know, they are very common items, which are get with many creatures.
and it would take me a long time to remove every piece of the set from monster.xml from all the monsters

I was thinking of something like this in code:
(The code is misspelled, it's just an idea, in case anyone knows how to write it properly)
Code:
local remove_bloked_loot = {
    {items = {
        {id = 2365},
        {id = 2392}
    }},
}

function Container:removeLootBlocked(c, t)
    for i = 1, #t.items do
        if t.items[i] then
        item:remove()
            end
        end
    end

function onDeath(creature, corpse, killer, mostDamage, unjustified, mostDamage_unjustified)
    if not creature:isMonster() then return true end
    if corpse and corpse:isContainer() then
        for i = 1, #remove_bloked_loot do
            corpse:removeLootBlocked(creature, remove_bloked_loot[i])
        end
    end
    return true
end
 
Solution
Hello, does anyone have any idea how to remove certain items from the loot that the monsters give?
An example, I want leather set to be obtained in Quests.

Leather Helmet, Leather Armor, Leather Legs, Leather Boots
as we all know, they are very common items, which are get with many creatures.
and it would take me a long time to remove every piece of the set from monster.xml from all the monsters

I was thinking of something like this in code:
(The code is misspelled, it's just an idea, in case anyone knows how to write it properly)
Code:
local remove_bloked_loot = {
    {items = {
        {id = 2365},
        {id = 2392}
    }},
}

function Container:removeLootBlocked(c, t)
    for i = 1, #t.items do
        if t.items[i]...
ctrl+shift+f / replace all with a spacebar...

It would be better to create a system were loot is getting added to the monster instead of removing them... (not that it isn't possible to remove loot, but i guess better performance wise instead of iterating every corpse)...
 
Hello, does anyone have any idea how to remove certain items from the loot that the monsters give?
An example, I want leather set to be obtained in Quests.

Leather Helmet, Leather Armor, Leather Legs, Leather Boots
as we all know, they are very common items, which are get with many creatures.
and it would take me a long time to remove every piece of the set from monster.xml from all the monsters

I was thinking of something like this in code:
(The code is misspelled, it's just an idea, in case anyone knows how to write it properly)
Code:
local remove_bloked_loot = {
    {items = {
        {id = 2365},
        {id = 2392}
    }},
}

function Container:removeLootBlocked(c, t)
    for i = 1, #t.items do
        if t.items[i] then
        item:remove()
            end
        end
    end

function onDeath(creature, corpse, killer, mostDamage, unjustified, mostDamage_unjustified)
    if not creature:isMonster() then return true end
    if corpse and corpse:isContainer() then
        for i = 1, #remove_bloked_loot do
            corpse:removeLootBlocked(creature, remove_bloked_loot[i])
        end
    end
    return true
end
Try this, not tested:
LUA:
local blockedItensIds = {2365, 2392}

function Container:getAllItems()
    local list = {}
    for index = 0, (self:getSize() - 1) do
        local item = self:getItem(index)
        if item then
            table.insert(list, item)
            if item:isContainer() then
                local rlist = item:getAllItems()
                if type(rlist) == 'table' then
                    for _, v in pairs(rlist) do
                        table.insert(list, v)
                    end
                end
            end
        end
    end
    return list
end

function onDeath(creature, corpse, killer, mostDamage, unjustified, mostDamage_unjustified)
    if not creature:isMonster() then return true end
    if corpse and corpse:isContainer() then
        local itensInCorpse = corpse:getAllItems() --Get all itens in corpse
        local itensToRemove = {} --new table to hold blocked itens userData in corpse
        for i = 1, #itensInCorpse do --for each item in corpse
            if isInArray(blockedItensIds, itensInCorpse[i]:getId()) then --if item in corpse is in blockedItensIds array
                table.insert(itensToRemove, itensInCorpse[i]) --insert item i in table to remove
            end
        end
        
        for i = 1, #itensToRemove do--for each item that need be removed
            if itensToRemove[i] then --if item still exist
                itensToRemove[i]:remove() --remove it
            end
        end
    end
    return true
end
This is what you asked for. But i realy recommend do what Animera and J.Dre said, obviously is the best option.
Again, the code is not tested, i haven't a server to test atm. Any problem let me know, when i get home i can test and help you.
 
Solution
open notepad++ > press ctrl+shift+f > select folder monsters > find for
Code:
.*"XXXX".*
(where XXXX is itemid you want to remove) > replace for empty string (nothing) > press replace all > done

Using .* before or after some string makes you search for the whole line that contains that string, thats why you're searching for "itemid" with .* before and after
 
1576191013215.png

go to data/monster

type item name/id in search bar (marked as 1 on the picture)

search in files (or "files content", depending on translation) (marked as 2)

open all files in notepad++

press ctrl+h

type item name/id in " " in replace dialog (top box) to make sure you didn't replace something else by accident

press "replace all in opened documents"
 
Hello friends, I am very happy with all of you for your collaborations and recommendations.

will be very useful notepad++ functions that taught me.

I was exploring more the functions of my TFS 1.3 server
and I think blocking items is very optimized with the function:
Code:
function Monster:onDropLoot(corpse)

I only added the following code, so the items is never created to be deleted afterwards.
Code:
local block = {2461, 2467, 2148}

for i=1, #block do
if item.itemId == block[i] then
itemCount = 0
end  
end

Again, thank you very much to all


I tried it, I register the event in monsters, but he script didn't do anything, I didn't get any mistakes in console, I don't know what happened.
but I already solved it with the function that I mentioned above.

Try this, not tested:
LUA:
local blockedItensIds = {2365, 2392}

function Container:getAllItems()
    local list = {}
    for index = 0, (self:getSize() - 1) do
        local item = self:getItem(index)
        if item then
            table.insert(list, item)
            if item:isContainer() then
                local rlist = item:getAllItems()
                if type(rlist) == 'table' then
                    for _, v in pairs(rlist) do
                        table.insert(list, v)
                    end
                end
            end
        end
    end
    return list
end

function onDeath(creature, corpse, killer, mostDamage, unjustified, mostDamage_unjustified)
    if not creature:isMonster() then return true end
    if corpse and corpse:isContainer() then
        local itensInCorpse = corpse:getAllItems() --Get all itens in corpse
        local itensToRemove = {} --new table to hold blocked itens userData in corpse
        for i = 1, #itensInCorpse do --for each item in corpse
            if isInArray(blockedItensIds, itensInCorpse[i]:getId()) then --if item in corpse is in blockedItensIds array
                table.insert(itensToRemove, itensInCorpse[i]) --insert item i in table to remove
            end
        end
      
        for i = 1, #itensToRemove do--for each item that need be removed
            if itensToRemove[i] then --if item still exist
                itensToRemove[i]:remove() --remove it
            end
        end
    end
    return true
end
This is what you asked for. But i realy recommend do what Animera and J.Dre said, obviously is the best option.
Again, the code is not tested, i haven't a server to test atm. Any problem let me know, when i get home i can test and help you.
 
Last edited:
Back
Top