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

For-loop index jump

Dries390

Well-Known Member
Joined
Sep 8, 2007
Messages
91
Solutions
4
Reaction score
70
Hello everyone,

I've been trying to implement a spell-salesman for knights and have run into an odd bug. The code works correctly for spells up until i=3, then skips to i=5 when asked for the "charge" spell. Does anybody know why this is? I'm using TFS 0.3.6 because I'm not really interested in features released beyond that point. Asking him for "protector" offers "whirlwind throw" and asking for the last two spells throws an error because it's trying to read table elements that are not there, i.e. spells with i > 15.

2019-03-20.png
 
Solution
You don't need all that loops, just go and index table values by strings, then you can skip most of it anyway
Lua:
local spells = {
["antidote"] = {...}
-- and so on
}

if spells[msg:lower()] then
-- found the spell
end
I'm on phone, else I would provide the full example
Hello everyone,

I've been trying to implement a spell-salesman for knights and have run into an odd bug. The code works correctly for spells up until i=3, then skips to i=5 when asked for the "charge" spell. Does anybody know why this is? I'm using TFS 0.3.6 because I'm not really interested in features released beyond that point. Asking him for "protector" offers "whirlwind throw" and asking for the last two spells throws an error because it's trying to read table elements that are not there, i.e. spells with i > 15.

View attachment 35520
The 1 at the end of i = 1, #spells, 1 is unnecessary. Using pairs may be a better solution here. Also you can just return the array itself instead of the index.

Lua:
function spellCheck(msg)
    for key, spell in pairs(spells) do
        if msg:lower() == spell.spell_name:lower() then
            return spell
        end
    end
end

local spell = spellCheck(msg)
if spell then
    -- do your stuff
end
 
Thank you for taking a look at this. It seems however that, even using pairs, the error stays the same. I have no explanation for why a simple loop over the table works but returns a wrong array in the function.
 
number 0?
also levels are like 10 35 60 25 which means 4(25) is lower than 60 so it goes to 90?
check 3 from groundshaker see if it happens there too
 
You don't need all that loops, just go and index table values by strings, then you can skip most of it anyway
Lua:
local spells = {
["antidote"] = {...}
-- and so on
}

if spells[msg:lower()] then
-- found the spell
end
I'm on phone, else I would provide the full example
 
Solution
Like Evil Hero pointed out above, use a table structure like:
Lua:
-- Structure your table like this, so that lowercase spell names are indices and they each hold an array of data related to the spell.
local spells = {
    ["antidote"] = {price = 150, words = "Exana Pox", level = 10},
    ["berserk"] = {price = 2500, words = "Exori", level = 35}
}

Then you can search for a specific spell with a specific unique index and be sure that you will always get the desired result:

Lua:
if spells[msg:lower()] then -- Checks if index exists in the spells table.
    -- Spell with name "msg" was found in the table.
    -- We can make more conditions here on what to do now after we found it.
else
    -- Player said a word which was not found as an index anywhere in the 'spells' table.
    selfSay("Sorry, such a spell does not exist.", cid)
end

If you want to iterate through such a table, you can use key/value pairs such as:
Lua:
for index, details in pairs(spells) do
        print("Details of spell: " .. index .. ": Costs - " .. details.price .. " gold and can be learned at level " .. details.level .. " with words " .. details.words .. ".")
end
 
Thank you for all the replies, I implemented Evilhero's method and it works now. In the end it seemed interesting that iterating over spells for i=1,15 gave the correct table while the function had those weird little jumps.

@Erexo: Originally the script had a local variable 'check' which was returned when the spell was found, i.e. check = i, return check if spell == spells.spell_name. In my trying to fix it I must have gotten some code scrambled up.
 
Back
Top