• 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+ Not sure how to handle nils on slotItems IFs

Oneda

Aspiring Spriter
Joined
Dec 3, 2013
Messages
157
Solutions
2
Reaction score
89
Location
Brazil
Been trying for a while now, works fine till you have none of the items equipped, which then makes the getSlotItem return nil. Not really sure how to proceed in with the nils, been bashing my head into the wall with this for a while now.

I know there might be a real dumb easy way to handle that nil, I'm just not able to figure it out (yeah, ffs)

Explaining on the script:
isGolden(player) returns true if player has any of the items in said slots, if not returns false. The rest is basically just for debugging purposes...

Lua:
function isGolden(player)
    if player:getSlotItem(CONST_SLOT_LEGS):getId() == 2470 or player:getSlotItem(CONST_SLOT_ARMOR):getId() == 2466 or player:getSlotItem(CONST_SLOT_HEAD):getId() == 2471 then
        return true
    else return false
    end
end

function onSay(player, words, param)
    if isGolden(player) then
        player:say("yep", TALKTYPE_MONSTER_SAY)
        return false
    else player:say("nope", TALKTYPE_MONSTER_SAY)
        return false
    end
end
 
Last edited:
Solution
You can do it also using loops.

Lua:
local slotsToCheck = {CONST_SLOT_HEAD, CONST_SLOT_ARMOR, CONST_SLOT_LEGS}
local goldenItems = {2466, 2470, 2471}

function countEquippedGoldenItems(player)
    local goldenItemsCount = 0

    for slotId in ipairs(slotsToCheck) do
        local item = player:getSlotItem(slotId)
        if item and table.contains(goldenItems, item:getId()) then
            goldenItemsCount = goldenItemsCount + 1
        end
    end

    return goldenItemsCount
end

function hasEquippedGoldenItem(player)
    for slotId in ipairs(slotsToCheck) do
        local item = player:getSlotItem(slotId)
        if item and table.contains(goldenItems, item:getId()) then
            return true
        end
    end

    return false...
OP
OP
Oneda

Oneda

Aspiring Spriter
Joined
Dec 3, 2013
Messages
157
Solutions
2
Reaction score
89
Location
Brazil
if not player:getSlotItem(slot) then return false end
That worked and also helped me realizing my if wasnt going to work as expected. Thanks!

Also reworked the script if anyone ever needs help studying:

Lua:
local armorId = 2466
local legsId = 2470
local helmetId = 2471

--local bonusConfig = {}

function setParts(player)
local goldCount = 0
local legCheck = 0
local armorCheck = 0
local helmetCheck = 0

    if player:getSlotItem(CONST_SLOT_LEGS) then
        legCheck = 1
    else legCheck = 0 end
    
    if player:getSlotItem(CONST_SLOT_ARMOR) then
        armorCheck = 1
    else armorCheck = 0 end
    
    if player:getSlotItem(CONST_SLOT_HEAD) then
        helmetCheck = 1
    else helmetCheck = 0 end
    
    
    if legCheck == 1 then
        if player:getSlotItem(CONST_SLOT_LEGS):getId() == legsId then
            goldCount = goldCount + 1
        end
    else goldCount = goldCount end
    
    if armorCheck == 1 then
        if player:getSlotItem(CONST_SLOT_ARMOR):getId() == armorId then
            goldCount = goldCount + 1
        end
    else goldCount = goldCount end
    
    if helmetCheck == 1 then
        if player:getSlotItem(CONST_SLOT_HEAD):getId() == helmetId then
            goldCount = goldCount + 1
        end
    else goldCount = goldCount end
    
    return goldCount
end

function onSay(player, words, param)
    if setParts(player) >= 1 then
        player:say(setParts(player), TALKTYPE_MONSTER_SAY)
        return false
    elseif setParts(player) <= 0 then
        player:say(setParts(player), TALKTYPE_MONSTER_SAY)
        return false
    end
end
 

esigma94

Well-Known Member
Joined
Nov 1, 2009
Messages
108
Solutions
17
Reaction score
86
You can do it also using loops.

Lua:
local slotsToCheck = {CONST_SLOT_HEAD, CONST_SLOT_ARMOR, CONST_SLOT_LEGS}
local goldenItems = {2466, 2470, 2471}

function countEquippedGoldenItems(player)
    local goldenItemsCount = 0

    for slotId in ipairs(slotsToCheck) do
        local item = player:getSlotItem(slotId)
        if item and table.contains(goldenItems, item:getId()) then
            goldenItemsCount = goldenItemsCount + 1
        end
    end

    return goldenItemsCount
end

function hasEquippedGoldenItem(player)
    for slotId in ipairs(slotsToCheck) do
        local item = player:getSlotItem(slotId)
        if item and table.contains(goldenItems, item:getId()) then
            return true
        end
    end

    return false
end

Above script assumes that item cannot be equipped in a different slot that his own so there's no need to ensure wheter helmet is in helmet slot. Due to that, there's no separation for golden items in a different slots.

If you want to check if item is in proper slot (coz you allow different type of items in it like for example arrow slot in old tibia) then you can make goldenItems a table with slot_ids as keys.

Lua:
local slotsToCheck = {CONST_SLOT_HEAD, CONST_SLOT_ARMOR, CONST_SLOT_LEGS}
local goldenItems = {
    [CONST_SLOT_HEAD] = {2471},
    [CONST_SLOT_ARMOR] = {2466},
    [CONST_SLOT_LEGS] = {2470}
}

function countEquippedGoldenItems(player)
    local goldenItemsCount = 0

    for slotId in ipairs(slotsToCheck) do
        local item = player:getSlotItem(slotId)
        if item and table.contains(goldenItems[slotId], item:getId()) then
            goldenItemsCount = goldenItemsCount + 1
        end
    end

    return goldenItemsCount
end

function hasEquippedGoldenItem(player)
    for slotId in ipairs(slotsToCheck) do
        local item = player:getSlotItem(slotId)
        if item and table.contains(goldenItems[slotId], item:getId()) then
            return true
        end
    end

    return false
end


If you want to go through all slots, you can even change for loop from for .. in .. form to count every slot. Like in following example.
Lua:
local goldenItems = {
    [CONST_SLOT_HEAD] = {2471},
    [CONST_SLOT_NECKLACE] = {},
    [CONST_SLOT_BACKPACK] = {},
    [CONST_SLOT_ARMOR] = {2466},
    [CONST_SLOT_RIGHT] = {},
    [CONST_SLOT_LEFT] = {},
    [CONST_SLOT_LEGS] = {2470},
    [CONST_SLOT_FEET] = {},
    [CONST_SLOT_RING] = {},
    [CONST_SLOT_AMMO] = {},
}

function countEquippedGoldenItems(player)
    local goldenItemsCount = 0

    for slotId = CONST_SLOT_HEAD, CONST_SLOT_AMMO do
        local item = player:getSlotItem(slotId)
        if item and table.contains(goldenItems[slotId], item:getId()) then
            goldenItemsCount = goldenItemsCount + 1
        end
    end

    return goldenItemsCount
end

function hasEquippedGoldenItem(player)
    for slotId = CONST_SLOT_HEAD, CONST_SLOT_AMMO do
        local item = player:getSlotItem(slotId)
        if item and table.contains(goldenItems[slotId], item:getId()) then
            return true
        end
    end

    return false
end
 
Solution
OP
OP
Oneda

Oneda

Aspiring Spriter
Joined
Dec 3, 2013
Messages
157
Solutions
2
Reaction score
89
Location
Brazil
You can do it also using loops.

Lua:
local slotsToCheck = {CONST_SLOT_HEAD, CONST_SLOT_ARMOR, CONST_SLOT_LEGS}
local goldenItems = {2466, 2470, 2471}

function countEquippedGoldenItems(player)
    local goldenItemsCount = 0

    for slotId in ipairs(slotsToCheck) do
        local item = player:getSlotItem(slotId)
        if item and table.contains(goldenItems, item:getId()) then
            goldenItemsCount = goldenItemsCount + 1
        end
    end

    return goldenItemsCount
end

function hasEquippedGoldenItem(player)
    for slotId in ipairs(slotsToCheck) do
        local item = player:getSlotItem(slotId)
        if item and table.contains(goldenItems, item:getId()) then
            return true
        end
    end

    return false
end

Above script assumes that item cannot be equipped in a different slot that his own so there's no need to ensure wheter helmet is in helmet slot. Due to that, there's no separation for golden items in a different slots.

If you want to check if item is in proper slot (coz you allow different type of items in it like for example arrow slot in old tibia) then you can make goldenItems a table with slot_ids as keys.

Lua:
local slotsToCheck = {CONST_SLOT_HEAD, CONST_SLOT_ARMOR, CONST_SLOT_LEGS}
local goldenItems = {
    [CONST_SLOT_HEAD] = {2471},
    [CONST_SLOT_ARMOR] = {2466},
    [CONST_SLOT_LEGS] = {2470}
}

function countEquippedGoldenItems(player)
    local goldenItemsCount = 0

    for slotId in ipairs(slotsToCheck) do
        local item = player:getSlotItem(slotId)
        if item and table.contains(goldenItems[slotId], item:getId()) then
            goldenItemsCount = goldenItemsCount + 1
        end
    end

    return goldenItemsCount
end

function hasEquippedGoldenItem(player)
    for slotId in ipairs(slotsToCheck) do
        local item = player:getSlotItem(slotId)
        if item and table.contains(goldenItems[slotId], item:getId()) then
            return true
        end
    end

    return false
end


If you want to go through all slots, you can even change for loop from for .. in .. form to count every slot. Like in following example.
Lua:
local goldenItems = {
    [CONST_SLOT_HEAD] = {2471},
    [CONST_SLOT_NECKLACE] = {},
    [CONST_SLOT_BACKPACK] = {},
    [CONST_SLOT_ARMOR] = {2466},
    [CONST_SLOT_RIGHT] = {},
    [CONST_SLOT_LEFT] = {},
    [CONST_SLOT_LEGS] = {2470},
    [CONST_SLOT_FEET] = {},
    [CONST_SLOT_RING] = {},
    [CONST_SLOT_AMMO] = {},
}

function countEquippedGoldenItems(player)
    local goldenItemsCount = 0

    for slotId = CONST_SLOT_HEAD, CONST_SLOT_AMMO do
        local item = player:getSlotItem(slotId)
        if item and table.contains(goldenItems[slotId], item:getId()) then
            goldenItemsCount = goldenItemsCount + 1
        end
    end

    return goldenItemsCount
end

function hasEquippedGoldenItem(player)
    for slotId = CONST_SLOT_HEAD, CONST_SLOT_AMMO do
        local item = player:getSlotItem(slotId)
        if item and table.contains(goldenItems[slotId], item:getId()) then
            return true
        end
    end

    return false
end

Welp, that cleans the code by alot, I will definetly try implementing loops on my own, thanks alot!

Edit: @esigma94 The first two bits of code gave me nil errors, the third one runs perfectly fine, maybe because the first ones arent handling slots without anything equipped correctly (the reason it returns nil) then the script breaks?

1627587016780.png
 
Last edited:
Top