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

local item issue

Nokturno

Not a human
Joined
Aug 7, 2009
Messages
558
Solutions
2
Reaction score
400
hello ppl.
im working on a script but im currently stuck in the code


Lua:
local function classifyLoot(position)
    local corpse = Tile(position):getTopDownItem()
    if not corpse then
        return false
    end
 
    -- Creating loot list
    local itemList = {}
    if ItemType(corpse:getId()):isContainer() then
        for i = corpse:getSize() - 1, 0, -1 do
            local item = corpse:getItem(i)
            if item then
                itemList[#itemList + 1] = item:getId()
            end
        end
    end
 
    -- Getting/Assigning tier
 local itemMaxRarity = 0
 local tierIndex, found = 0, false
 for _, item in ipairs(itemList) do -- check all items in table
    local itemRarity = item:getRarity() -- check rarity levels
    -- need to add check for uncommon items
    if itemRarity > itemMaxRarity then -- if current item is higher tier than previous item
        local itemMaxRarity = itemRarity -- assign highest rarity level
    end   
    found = true
 end
 
    -- Transforming corpse
local uncommon = {bag = 1991, effect = 36, tier = "uncommon"}
  local rare = {bag = 1991, effect = 36, tier = "rare"}
  local epic = {bag = 1993, effect = 207, tier = "epic"}
  local legendary = {bag = 1997, effect = 177, tier = "legendary"}
    if found then -- when tier item is found
      if itemMaxRarity == 1 then
      corpse:transform(uncommon.bag)
      position:sendMagicEffect(uncommon.effect)
      effectLoop(position, uncommon.effect)
      local tierPhrase = uncommon.tier
      elseif itemMaxRarity == 2 then
      corpse:transform(rare.bag)
      position:sendMagicEffect(rare.effect)
      effectLoop(position, rare.effect)
      local tierPhrase = rare.tier
      elseif itemMaxRarity == 3 then
      corpse:transform(epic.bag)
      position:sendMagicEffect(epic.effect)
      effectLoop(position, epic.effect)
      local tierPhrase = epic.tier
      elseif itemMaxRarity == 4 then
      corpse:transform(legendary.bag)
      position:sendMagicEffect(legendary.effect)
      effectLoop(position, legendary.effect)
      local tierPhrase = legendary.tier
      end
          
        local spectators = Game.getSpectators(position, false, true, 7, 7, 5, 5)
        if #spectators > 0 then
        for i = 1, #spectators do
        spectators[i]:say(tierPhrase, TALKTYPE_MONSTER_SAY, false, spectators[i], position)
      end
    end
    else
        -- Default tier
        corpse:transform(1996)
        position:sendMagicEffect(31)
    end
end
Code:

ERROR:
Lua:
data/creaturescripts/scripts/customLoot.lua:49: attempt to index local 'item' (a number value)
stack traceback:
        [C]: in function '__inde
Code:

Cant get the function index the local 'item'
Code:
for _, item in ipairs(itemList) do

dont know if someone can help me out with this?
 
Solution
Sorry, I have left your effects function as it was, please try this new version:
Lua:
local function effectLoop(position, effect)
    local bagIds = {1991, 1992, 1993, 1997, 1996}
    local active = false
    for _, bag in ipairs(bagIds) do
        local lootBag = Tile(position):getItemById(bag)
        if lootBag then
            active = true
            break
        end
    end
    if active then
        position:sendMagicEffect(effect)
        addEvent(effectLoop, 200, position, effect)
    end
end

local rarityList = {
    {bag = 1991, effect = 36, tier = "uncommon"},
    {bag = 1991, effect = 36, tier = "rare"},
    {bag = 1993, effect = 207, tier = "epic"},
    {bag = 1997, effect = 177, tier = "legendary"}
}

local function...
hello ppl.
im working on a script but im currently stuck in the code


Lua:
local function classifyLoot(position)
    local corpse = Tile(position):getTopDownItem()
    if not corpse then
        return false
    end
 
    -- Creating loot list
    local itemList = {}
    if ItemType(corpse:getId()):isContainer() then
        for i = corpse:getSize() - 1, 0, -1 do
            local item = corpse:getItem(i)
            if item then
                itemList[#itemList + 1] = item:getId()
            end
        end
    end
 
    -- Getting/Assigning tier
 local itemMaxRarity = 0
 local tierIndex, found = 0, false
 for _, item in ipairs(itemList) do -- check all items in table
    local itemRarity = item:getRarity() -- check rarity levels
    -- need to add check for uncommon items
    if itemRarity > itemMaxRarity then -- if current item is higher tier than previous item
        local itemMaxRarity = itemRarity -- assign highest rarity level
    end   
    found = true
 end
 
    -- Transforming corpse
local uncommon = {bag = 1991, effect = 36, tier = "uncommon"}
  local rare = {bag = 1991, effect = 36, tier = "rare"}
  local epic = {bag = 1993, effect = 207, tier = "epic"}
  local legendary = {bag = 1997, effect = 177, tier = "legendary"}
    if found then -- when tier item is found
      if itemMaxRarity == 1 then
      corpse:transform(uncommon.bag)
      position:sendMagicEffect(uncommon.effect)
      effectLoop(position, uncommon.effect)
      local tierPhrase = uncommon.tier
      elseif itemMaxRarity == 2 then
      corpse:transform(rare.bag)
      position:sendMagicEffect(rare.effect)
      effectLoop(position, rare.effect)
      local tierPhrase = rare.tier
      elseif itemMaxRarity == 3 then
      corpse:transform(epic.bag)
      position:sendMagicEffect(epic.effect)
      effectLoop(position, epic.effect)
      local tierPhrase = epic.tier
      elseif itemMaxRarity == 4 then
      corpse:transform(legendary.bag)
      position:sendMagicEffect(legendary.effect)
      effectLoop(position, legendary.effect)
      local tierPhrase = legendary.tier
      end
          
        local spectators = Game.getSpectators(position, false, true, 7, 7, 5, 5)
        if #spectators > 0 then
        for i = 1, #spectators do
        spectators[i]:say(tierPhrase, TALKTYPE_MONSTER_SAY, false, spectators[i], position)
      end
    end
    else
        -- Default tier
        corpse:transform(1996)
        position:sendMagicEffect(31)
    end
end
Code:

ERROR:
Lua:
data/creaturescripts/scripts/customLoot.lua:49: attempt to index local 'item' (a number value)
stack traceback:
        [C]: in function '__inde
Code:

Cant get the function index the local 'item'
Code:
for _, item in ipairs(itemList) do

dont know if someone can help me out with this?
Lua:
itemList[#itemList + 1] = item:getId()

You're getting the number value here.
If you want the actual item.. do something like this?
Lua:
itemList[#itemList + 1] = item
 
the problem is that is not getting index at line 21
But... it's clearly finding the index.. since it's finding the number values in your table.

If there was an issue with the index, it would tell you it's a nil value.

Untitled.png
 
Your code can be reduced to this:
Lua:
local function classifyLoot(position)
    local corpse = Tile(position):getTopDownItem()
    if not corpse or not corpse:getType():isContainer() then
        return false
    end
    -- Creating loot list
    local itemList = {}
    for i = corpse:getSize() - 1, 0, -1 do
        local item = corpse:getItem(i)
        if item then
            itemList[#itemList + 1] = item
        end
    end
    if #itemList > 1 then
        table.sort(itemList, function (i1, i2) return i1:getRarity() > i2:getRarity() end)
    end
    local itemMaxRarity = itemList[1]:getRarity()
    if itemMaxRarity == 0 then
        -- Default tier
        corpse:transform(1996)
        position:sendMagicEffect(31)
        return
    end
    -- Transforming corpse
    local transformation = ({
        {bag = 1991, effect = 36, tier = "uncommon"},
        {bag = 1991, effect = 36, tier = "rare"},
        {bag = 1993, effect = 207, tier = "epic"},
        {bag = 1997, effect = 177, tier = "legendary"}
    })[itemMaxRarity]
    corpse:transform(transformation.bag)
    position:sendMagicEffect(transformation.effect)
    local spectators = Game.getSpectators(position, false, true, 7, 7, 5, 5)
    if #spectators > 0 then
        spectators[1]:say(transformation.tier, TALKTYPE_MONSTER_SAY, false, nil, position)
    end
end
 
Last edited:
@Sarah Wesker i applied your sugestion but ended up with this


Lua:
local function effectLoop(position, effect)
    local bagIds = {1991, 1992, 1993, 1997, 1996}
    local active = false
    for _, bag in ipairs(bagIds) do
            local lootBag = Tile(position):getItemById(bag)
            if lootBag then
                active = true
                break
            end
    end
    if active then
        position:sendMagicEffect(effect)
        addEvent(effectLoop, 200, position, effect)
    end
end
 
local function classifyLoot(position)
    local corpse = Tile(position):getTopDownItem()
    if not corpse or not corpse:getType():isContainer() then
        return false
    end
    -- Creating loot list
    local itemList = {}
    for i = corpse:getSize() - 1, 0, -1 do
        local item = corpse:getItem(i)
        if item then
            itemList[#itemList + 1] = item
        end
    end
    if #itemList > 1 then
        table.sort(itemList, function (i1, i2) return i1:getRarity() > i2:getRarity() end)
    end
    local itemMaxRarity = itemList[1]:getRarity()
    if itemMaxRarity == 0 then
        -- Default tier
        corpse:transform(1996)
        position:sendMagicEffect(31)
        return
    end
    -- Transforming corpse
    local transformation = ({
        {bag = 1991, effect = 36, tier = "uncommon"},
        {bag = 1991, effect = 36, tier = "rare"},
        {bag = 1993, effect = 207, tier = "epic"},
        {bag = 1997, effect = 177, tier = "legendary"}
    })[itemMaxRarity]
    corpse:transform(transformation.bag)
    position:sendMagicEffect(transformation.effect)
    local spectators = Game.getSpectators(position, false, true, 7, 7, 5, 5)
    if #spectators > 0 then
        spectators[1]:say(transformation.tier, TALKTYPE_MONSTER_SAY, false, nil, position)
    end
end
 
function onKill(player, target)
    if not target:isMonster() or target:getMaster() then
        return true
    end
    addEvent(classifyLoot, 1, target:getPosition())
    return true
end

error 3.png
 
@Sarah Wesker i applied your sugestion but ended up with this


Lua:
local function effectLoop(position, effect)
    local bagIds = {1991, 1992, 1993, 1997, 1996}
    local active = false
    for _, bag in ipairs(bagIds) do
            local lootBag = Tile(position):getItemById(bag)
            if lootBag then
                active = true
                break
            end
    end
    if active then
        position:sendMagicEffect(effect)
        addEvent(effectLoop, 200, position, effect)
    end
end

local function classifyLoot(position)
    local corpse = Tile(position):getTopDownItem()
    if not corpse or not corpse:getType():isContainer() then
        return false
    end
    -- Creating loot list
    local itemList = {}
    for i = corpse:getSize() - 1, 0, -1 do
        local item = corpse:getItem(i)
        if item then
            itemList[#itemList + 1] = item
        end
    end
    if #itemList > 1 then
        table.sort(itemList, function (i1, i2) return i1:getRarity() > i2:getRarity() end)
    end
    local itemMaxRarity = itemList[1]:getRarity()
    if itemMaxRarity == 0 then
        -- Default tier
        corpse:transform(1996)
        position:sendMagicEffect(31)
        return
    end
    -- Transforming corpse
    local transformation = ({
        {bag = 1991, effect = 36, tier = "uncommon"},
        {bag = 1991, effect = 36, tier = "rare"},
        {bag = 1993, effect = 207, tier = "epic"},
        {bag = 1997, effect = 177, tier = "legendary"}
    })[itemMaxRarity]
    corpse:transform(transformation.bag)
    position:sendMagicEffect(transformation.effect)
    local spectators = Game.getSpectators(position, false, true, 7, 7, 5, 5)
    if #spectators > 0 then
        spectators[1]:say(transformation.tier, TALKTYPE_MONSTER_SAY, false, nil, position)
    end
end

function onKill(player, target)
    if not target:isMonster() or target:getMaster() then
        return true
    end
    addEvent(classifyLoot, 1, target:getPosition())
    return true
end

View attachment 55536
The getRarity function is supposed to return a number, such as the rarity level of an article, but according to the bug report, the function is returning a table, if you show me the getRarity function I can help you solve the problem, if you want
 
Thks everyone for your help.
@Sarah Wesker ty for your time. this is oens function btw
this is the function:


Lua:
function Item.getRarity(self)
  return self:getCustomAttribute("rarity") and US_CONFIG.RARITY[self:getCustomAttribute("rarity")] or US_CONFIG.RARITY[COMMON]
end

And this is US_CONFIG.RARITY


Lua:
RARITY = {
    [COMMON] = {
      name = "[COMMON]",
      maxBonus = 1, -- max amount of bonus attributes
      chance = 1 -- 1:X chance that item will be common (1 = 100%)
    },
    [RARE] = {
      name = "[RARE]",
      maxBonus = 2, -- max amount of bonus attributes
      chance = 10 -- 1:X chance that item will be common (1 = 100%)
    },
    [EPIC] = {
      name = "[EPIC]",
      maxBonus = 3, -- max amount of bonus attributes
      chance = 30 -- 1:X chance that item will be common (1 = 100%)
    },
    [LEGENDARY] = {
      name = "[LEGENDARY]",
      maxBonus = 4, -- max amount of bonus attributes
      chance = 80 -- 1:X chance that item will be common (1 = 100%)
    }
 
Lua:
local function effectLoop(position, effect)
    for _, bag in pairs({1991, 1992, 1993, 1997, 1996}) do
        if Tile(position):getItemById(bag) then
            position:sendMagicEffect(effect)
            addEvent(effectLoop, 200, position, effect)
            break
        end
    end
end

local function getRarityIndex(item)
    return item:getCustomAttribute("rarity") or 0
end

local rarityList = {
    {bag = 1991, effect = 36, tier = "uncommon"},
    {bag = 1991, effect = 36, tier = "rare"},
    {bag = 1993, effect = 207, tier = "epic"},
    {bag = 1997, effect = 177, tier = "legendary"}
}

local function classifyLoot(position)
    local corpse = Tile(position):getTopDownItem()
    if not corpse or not corpse:getType():isContainer() then
        return false
    end
    -- Creating loot list
    local itemList = {}
    for i = corpse:getSize() - 1, 0, -1 do
        local item = corpse:getItem(i)
        if item then
            itemList[#itemList + 1] = item
        end
    end
    if #itemList > 1 then
        table.sort(itemList, function (i1, i2) return getRarityIndex(i1) > getRarityIndex(i2) end)
    end
    -- Transforming corpse
    local transformation = rarityList[getRarityIndex(itemList[1])]
    if transformation then
        corpse:transform(transformation.bag)
        position:sendMagicEffect(transformation.effect)
        local spectators = Game.getSpectators(position, false, true, 7, 7, 5, 5)
        if #spectators > 0 then
            spectators[1]:say(transformation.tier, TALKTYPE_MONSTER_SAY, false, nil, position)
        end
    else
        -- Default tier
        corpse:transform(1996)
        position:sendMagicEffect(31)
    end
end
 
function onKill(player, target)
    if not target:isMonster() or target:getMaster() then
        return true
    end
    addEvent(classifyLoot, 1, target:getPosition())
    return true
end
much better with the information you gave
 
@Sarah Wesker really thankful for helping me here.
the system is generating the bags also the getrarity function works now
but, I got 2 issues.
first one is that function effectloot stopped working
second: i got this nil value on line 12

error a.png
 
Sorry, I have left your effects function as it was, please try this new version:
Lua:
local function effectLoop(position, effect)
    local bagIds = {1991, 1992, 1993, 1997, 1996}
    local active = false
    for _, bag in ipairs(bagIds) do
        local lootBag = Tile(position):getItemById(bag)
        if lootBag then
            active = true
            break
        end
    end
    if active then
        position:sendMagicEffect(effect)
        addEvent(effectLoop, 200, position, effect)
    end
end

local rarityList = {
    {bag = 1991, effect = 36, tier = "uncommon"},
    {bag = 1991, effect = 36, tier = "rare"},
    {bag = 1993, effect = 207, tier = "epic"},
    {bag = 1997, effect = 177, tier = "legendary"}
}

local function classifyLoot(position)
    local corpse = Tile(position):getTopDownItem()
    if not corpse or not corpse:getType():isContainer() then
        return false
    end
    -- Found max rarity
    local foundRarity = 0
    for i = corpse:getSize() - 1, 0, -1 do
        local item = corpse:getItem(i)
        if item then
            local rarityIndex = item:getCustomAttribute("rarity") or 0
            if rarityIndex > foundRarity then
                foundRarity = rarityIndex
            end
        end
    end
    -- Transforming corpse
    local transformation = rarityList[foundRarity]
    if transformation then
        corpse:transform(transformation.bag)
        position:sendMagicEffect(transformation.effect)
        local spectators = Game.getSpectators(position, false, true, 7, 7, 5, 5)
        if #spectators > 0 then
            spectators[1]:say(transformation.tier, TALKTYPE_MONSTER_SAY, false, nil, position)
        end
    else
        -- Default tier
        corpse:transform(1996)
        position:sendMagicEffect(31)
    end
end
 
function onKill(player, target)
    if not target:isMonster() or target:getMaster() then
        return true
    end
    addEvent(classifyLoot, 1, target:getPosition())
    return true
end
 
Solution
Back
Top