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

Lua Increase drop count by item name

E

Evil Puncker

Guest
if monster drop any item of the table (I'd like to use item names, but ID is fine too), it will MULTIPLY it by the random amount between min and max count chance, lets say a chicken dropped 2 chicken feathers, when I open the corpse there will be the amount of [formula(2 MULTIPLIED BY random 2 to 50 from the table bonus)] (probability to drop from 4 to 100 chicken feathers)(0 if no chicken feather dropped), thanks in advanced! I even tried to make it with some other code but no success :p

I'm using TFS 1.3 latest

Lua:
-- pseudo table
local config = {
    [1] = {itemname = "chicken feather", rate = {2, 50}},
    [2] = {itemname = "soul orb", rate = {1, 5}}
}

local function scanContainer(cid, position)
    local player = Player(cid)
    if not player then
        return
    end
    local corpse = Tile(position):getTopDownItem()
    if not corpse or not corpse:isContainer() then
        return
    end
    if corpse:getType():isCorpse() and corpse:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == cid then
        for a = corpse:getSize() - 1, 0, -1 do
            local containerItem = corpse:getItem(a)
            if containerItem then
                if player then
                    -- pseudo code start
                    if isItemStackable(containerItem:getId()) then
                        local targetName = config[ItemType(name):getId()]
                        local rate = math.random(table values between {x and y})
                        if not targetName then
                            return true
                        end
                        Container(corpse):addItem(ItemType("itemname"):getId()[], droppedItemCount * rate)
                    end
                    -- pseudo code end
                end
            end
        end
    end
end

function onKill(player, target)
    if not target:isMonster() then
        return true
    end
    addEvent(scanContainer, 10, player:getId(), target:getPosition())
    return true
end
 
Last edited by a moderator:
Solution
Lua:
local config = {
    ['chicken feather'] = {2, 50},
    ['soul orb'] = {1, 5}
}

local function scanContainer(cid, position)
    local player = Player(cid)
    if not player then
        return
    end
    local corpse = Tile(position):getTopDownItem()
    if not corpse or not corpse:isContainer() then
        return
    end
    if corpse:getType():isCorpse() and corpse:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == cid then
        for index = corpse:getSize() - 1, 0, -1 do
            local containerItem = corpse:getItem(index)
            local itemType = ItemType(containerItem:getId())
            local multiplier = config[itemType:getName():lower()]
            if multiplier and itemType:isStackable() then...
if monster drop any item of the table (I'd like to use item names, but ID is fine too), it will MULTIPLY it by the random amount between min and max count chance, lets say a chicken dropped 2 chicken feathers, when I open the corpse there will be the amount of [formula(2 MULTIPLIED BY random 2 to 50 from the table bonus)] (probability to drop from 4 to 100 chicken feathers)(0 if no chicken feather dropped), thanks in advanced! I even tried to make it with some other code but no success :p

I'm using TFS 1.3 latest

Lua:
-- pseudo table
local config = {
    [1] = {itemname = "chicken feather", rate = {2, 50}},
    [2] = {itemname = "soul orb", rate = {1, 5}}
}

local function scanContainer(cid, position)
    local player = Player(cid)
    if not player then
        return
    end
    local corpse = Tile(position):getTopDownItem()
    if not corpse or not corpse:isContainer() then
        return
    end
    if corpse:getType():isCorpse() and corpse:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == cid then
        for a = corpse:getSize() - 1, 0, -1 do
            local containerItem = corpse:getItem(a)
            if containerItem then
                if player then
                    -- pseudo code start
                    if isItemStackable(containerItem:getId()) then
                        local targetName = config[ItemType(name):getId()]
                        local rate = math.random(table values between {x and y})
                        if not targetName then
                            return true
                        end
                        Container(corpse):addItem(ItemType("itemname"):getId()[], droppedItemCount * rate)
                    end
                    -- pseudo code end
                end
            end
        end
    end
end

function onKill(player, target)
    if not target:isMonster() then
        return true
    end
    addEvent(scanContainer, 10, player:getId(), target:getPosition())
    return true
end
Hello,
I did this code and don't tested, please try:

Lua:
local config = {
    ["chicken feather"] = {rate = {2, 50}},
    ["soul orb"] = {rate = {1, 5}}
}

local function scanContainer(cid, position)
    local player = Player(cid)
    if not player then
        return false
    end
    local corpse = Tile(position):getTopDownItem()
    if not corpse or not corpse:isContainer() then
        return false
    end
    if corpse:getType():isCorpse() and corpse:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == cid then
        for a = corpse:getSize() - 1, 0, -1 do
            local containerItem = corpse:getItem(a)
            if containerItem then
                if config[string.lower(containerItem:getName())] then
                    local rate = math.random(config[containerItem:getName()].rate[1], config[containerItem:getName()].rate[2])
                    local alreadyDroped = containerItem:getCount()
                    corpse:addItem(containerItem:getId(), (alreadyDroped * rate) - alreadyDroped)
                end
            end
        end
    end
    return true
end

function onKill(player, target)
    if not target:isMonster() then
        return true
    end
    addEvent(scanContainer, 10, player:getId(), target:getPosition())
    return true
end
In line 19 i set item name to lowercase because in config table is in lowercase, not sure if is needed, u can remove the function and test it.
In line 22, i added the count thats need to reach true amount like: Droped 2 Chicken Feather and rate is 50, then have to be 100 Chicken Feather in total, i do: (dropedCount(2) * rate(50)) - dropedCount(2) = 98 because in corpse already have 2 original Chicken Feather.
I think will work. Good Luck.
AGAIN, DON'T TESTED.
 
Lua:
local config = {
    ['chicken feather'] = {2, 50},
    ['soul orb'] = {1, 5}
}

local function scanContainer(cid, position)
    local player = Player(cid)
    if not player then
        return
    end
    local corpse = Tile(position):getTopDownItem()
    if not corpse or not corpse:isContainer() then
        return
    end
    if corpse:getType():isCorpse() and corpse:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == cid then
        for index = corpse:getSize() - 1, 0, -1 do
            local containerItem = corpse:getItem(index)
            local itemType = ItemType(containerItem:getId())
            local multiplier = config[itemType:getName():lower()]
            if multiplier and itemType:isStackable() then
                containerItem:transform(itemType:getId(), math.min(100, containerItem:getCount() * math.random(multiplier[1], multiplier[2])))
            end
        end
    end
end

function onKill(player, target)
    if not target:isMonster() then
        return true
    end
    addEvent(scanContainer, 10, player:getId(), target:getPosition())
    return true
end
Simply just check if it's stackable and use math.min to keep control of maximum stack size after multiplication, use the item:transform(id, count) method rather than adding a new item to avoid the corpse overflowing.
 
Solution
Lua:
local config = {
    ['chicken feather'] = {2, 50},
    ['soul orb'] = {1, 5}
}

local function scanContainer(cid, position)
    local player = Player(cid)
    if not player then
        return
    end
    local corpse = Tile(position):getTopDownItem()
    if not corpse or not corpse:isContainer() then
        return
    end
    if corpse:getType():isCorpse() and corpse:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == cid then
        for index = corpse:getSize() - 1, 0, -1 do
            local containerItem = corpse:getItem(index)
            local itemType = ItemType(containerItem:getId())
            local multiplier = config[itemType:getName():lower()]
            if multiplier and itemType:isStackable() then
                containerItem:transform(itemType:getId(), math.min(100, containerItem:getCount() * math.random(multiplier[1], multiplier[2])))
            end
        end
    end
end

function onKill(player, target)
    if not target:isMonster() then
        return true
    end
    addEvent(scanContainer, 10, player:getId(), target:getPosition())
    return true
end
Simply just check if it's stackable and use math.min to keep control of maximum stack size after multiplication, use the item:transform(id, count) method rather than adding a new item to avoid the corpse overflowing.
Always amazing!
In item:transform(id, count) count can be more than 100? It Will add a New stack to corpse? Is really needed getName():lower to access the table Index or itsn't case-sensentive?
 
Always amazing!
In item:transform(id, count) count can be more than 100? It Will add a New stack to corpse? Is really needed getName():lower to access the table Index or itsn't case-sensentive?
No it can't, I just couldn't remember if internally it forces a maximum stack like I did with math.min (I checked now and it does, so you can only transform up to a stack of 100).
The lower() isn't needed but it's easier and more flexible if you'd like to add more items without risking missing a capital letter in the name and having it not work, but yes it is case-sensitive.
 
No it can't, I just couldn't remember if internally it forces a maximum stack like I did with math.min (I checked now and it does, so you can only transform up to a stack of 100).
The lower() isn't needed but it's easier and more flexible if you'd like to add more items without risking missing a capital letter in the name and having it not work, but yes it is case-sensitive.
Then should have a check If new count has more than 100, and use additem() to add a new stack, right?
 
Then should have a check If new count has more than 100, and use additem() to add a new stack, right?
Depends if @Evil Puncker wants to have a maximum of 100 for the multiplied item. If not, then a new issue comes with that because you could be trying to insert more items into the corpse than it can fit.
 
Depends if @Evil Puncker wants to have a maximum of 100 for the multiplied item. If not, then a new issue comes with that because you could be trying to insert more items into the corpse than it can fit.
Yes... Can you think any way to solve this? O think remove the original item and put a container(bag) and new itens inside isn't Nice... Have a way to incress the container(corpse) size If needed?(i Will look at backpack imbuiments that incress size)
I played a OT some time Ago, that corpses don't have size limit, how can i do that?

Should i create a New thread to discuss about this? This Topic is already solves, can we talk about this here?
 
Back
Top