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

Solved Attempt to index a nil value problem [TFS 1.2]

Joined
Jul 18, 2014
Messages
193
Solutions
2
Reaction score
15
Hi, i was making this new script for a quest but when i want to use the towers to teleport myself to the right position, in console appears
towersbosses.lua:14: attempt to index a nil value

This is my script: (IT'S TFS 1.2)
Code:
function onUse(player, fromPosition, item, toPosition, itemEx)

local undergrounds = {
[4567] = {newPos = {x = 246, y = 116, z = 11}, creature = "Red Undergrounder", creaturepos = {x = 241, y = 116, z = 11}},
[4568] = {newPos = {x = 283, y = 116, z = 11}, creature = "Green Undergrounder", creaturepos = {x = 277, y = 116, z = 11}},
[4569] = {newPos = {x = 312, y = 116, z = 11}, creature = "Yellow Undergrounder", creaturepos = {x = 304, y = 116, z = 11}},
[4560] = {newPos = {x = 360, y = 116, z = 11}, creature = "Blue Undergrounder", creaturepos = {x = 354, y = 113, z = 11}}
}
local finalboss = {
[4562] = {newPos = {x = 360, y = 116, z = 11}, creature = "Undergrounder", creaturepos = {x = 354, y = 113, z = 11}}
}

    if player:getStorageValue(undergrounds[item.actionid]) < 1 then
        player:teleportTo(undergrounds[item.actionid].newPos)
        doCreatureSay(cid, "Muahahaha!...", TALKTYPE_ORANGE_1)
        if getGlobalStorageValue(undergrounds[item.actionid]) < 1 then
            doSummonCreature(undergrounds[item.actionid].creature, undergrounds[item.actionid].creaturepos)
            setGlobalStorageValue(undergrounds[item.actionid], 1)
        end
    else
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The cave looks bad, you can't pass there any more.")
    end

    if player:getStorageValue(finalboss[item.uid]) < 1 and player:getStorageValue(undergrounds[item.actionid]) == 2 then
        player:teleportTo(finalboss[item.uid].newPos)
        doCreatureSay(cid, "Death Sentence...", TALKTYPE_ORANGE_1)
        if getGlobalStorageValue(finalboss[item.uid]) < 1 then
            doSummonCreature(finalboss[item.uid].creature, finalboss[item.uid].creaturepos)
            setGlobalStorageValue(finalboss[item.uid], 1)
        end
    elseif player:getStorageValue(finalboss[item.uid]) == 2 then
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The Undergrounder has been defeated. You can't pass there any more.")
    end
    return true
end

Please help:(
Thanks.
 
I already fixed re-writting the code. If you want to know what the hell i did, this is the new code:
Code:
function onUse(cid, item, fromPosition, toPosition, itemEx)

local colorunder = {
[4560] = {newPos = {x = 246, y = 116, z = 11}, creature = "Red Undergrounder", creaturepos = {x = 241, y = 116, z = 11}, storage = 4560},
[4561] = {newPos = {x = 283, y = 116, z = 11}, creature = "Green Undergrounder", creaturepos = {x = 277, y = 116, z = 11}, storage = 4561},
[4562] = {newPos = {x = 312, y = 116, z = 11}, creature = "Yellow Undergrounder", creaturepos = {x = 304, y = 116, z = 11}, storage = 4562},
[4563] = {newPos = {x = 360, y = 116, z = 11}, creature = "Blue Undergrounder", creaturepos = {x = 354, y = 113, z = 11}, storage = 4563}
}

local undersconfig = colorunder[item.uid]
local player = Player(cid)
    if getPlayerStorageValue(cid, undersconfig.storage) < 1 then
        player:teleportTo(undersconfig.newPos)
        doCreatureSay(cid, "Muahahaha!...", TALKTYPE_ORANGE_1)
        if getGlobalStorageValue(undersconfig.storage) < 1 then
            setGlobalStorageValue(undersconfig.storage, 1)
            Game.createMonster(undersconfig.creature, undersconfig.creaturepos)
        end
    else
        doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "The cave looks bad, you can't pass there any more.")
        return true
    end
return true
end

And i changed the actionids for uniqueids and changed the value ^^
Thanks to all for your time :)
 
The order doesnt matter
The order matters 110%

I already fixed re-writting the code. If you want to know what the hell i did, this is the new code:
Code:
function onUse(cid, item, fromPosition, toPosition, itemEx)

local colorunder = {
[4560] = {newPos = {x = 246, y = 116, z = 11}, creature = "Red Undergrounder", creaturepos = {x = 241, y = 116, z = 11}, storage = 4560},
[4561] = {newPos = {x = 283, y = 116, z = 11}, creature = "Green Undergrounder", creaturepos = {x = 277, y = 116, z = 11}, storage = 4561},
[4562] = {newPos = {x = 312, y = 116, z = 11}, creature = "Yellow Undergrounder", creaturepos = {x = 304, y = 116, z = 11}, storage = 4562},
[4563] = {newPos = {x = 360, y = 116, z = 11}, creature = "Blue Undergrounder", creaturepos = {x = 354, y = 113, z = 11}, storage = 4563}
}

local undersconfig = colorunder[item.uid]
local player = Player(cid)
    if getPlayerStorageValue(cid, undersconfig.storage) < 1 then
        player:teleportTo(undersconfig.newPos)
        doCreatureSay(cid, "Muahahaha!...", TALKTYPE_ORANGE_1)
        if getGlobalStorageValue(undersconfig.storage) < 1 then
            setGlobalStorageValue(undersconfig.storage, 1)
            Game.createMonster(undersconfig.creature, undersconfig.creaturepos)
        end
    else
        doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "The cave looks bad, you can't pass there any more.")
        return true
    end
return true
end

And i changed the actionids for uniqueids and changed the value ^^
Thanks to all for your time :)

You should really use metatables for everything, not just some things
Code:
function onUse(player, item, fromPosition, target, toPosition, isHotkey)

    local colorunder = {
        [4560] = {newPos = {x = 246, y = 116, z = 11}, creature = "Red Undergrounder", creaturepos = {x = 241, y = 116, z = 11}, storage = 4560},
        [4561] = {newPos = {x = 283, y = 116, z = 11}, creature = "Green Undergrounder", creaturepos = {x = 277, y = 116, z = 11}, storage = 4561},
        [4562] = {newPos = {x = 312, y = 116, z = 11}, creature = "Yellow Undergrounder", creaturepos = {x = 304, y = 116, z = 11}, storage = 4562},
        [4563] = {newPos = {x = 360, y = 116, z = 11}, creature = "Blue Undergrounder", creaturepos = {x = 354, y = 113, z = 11}, storage = 4563}
    }

    local undersconfig = colorunder[item.uid]
    if player:getStorageValue(undersconfig.storage) < 1 then
        player:teleportTo(undersconfig.newPos)
        player:say("Muahahaha!...", TALKTYPE_ORANGE_1)
        if Game.getStorageValue(undersconfig.storage) < 1 then
            Game.setStorageValue(undersconfig.storage, 1)
            Game.createMonster(undersconfig.creature, undersconfig.creaturepos)
        end
    else
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The cave looks bad, you can't pass there any more.")
        return true
    end
    return true
end
 
if item.actionid is nil then the index values of undergrounds & finalboss are not properly assigned to the item you are using, have you made sure the index values are assigned to actions.xml?
if item.actionid is nil then the object is not an item and it has nothing to do with the tables. The issue was that the function arguments were in the wrong order and so the item was actually a position not an item.
 
if item.actionid is nil then the object is not an item and it has nothing to do with the tables. The issue was that the function arguments were in the wrong order and so the item was actually a position not an item.
But i put the code:
Code:
function onUse(cid, item, fromPosition, toPosition, itemEx)

local colorunder = {
[4560] = {newPos = {x = 246, y = 116, z = 11}, creature = "Red Undergrounder", creaturepos = {x = 241, y = 116, z = 11}, storage = 4560},
[4561] = {newPos = {x = 283, y = 116, z = 11}, creature = "Green Undergrounder", creaturepos = {x = 277, y = 116, z = 11}, storage = 4561},
[4562] = {newPos = {x = 312, y = 116, z = 11}, creature = "Yellow Undergrounder", creaturepos = {x = 304, y = 116, z = 11}, storage = 4562},
[4563] = {newPos = {x = 360, y = 116, z = 11}, creature = "Blue Undergrounder", creaturepos = {x = 354, y = 113, z = 11}, storage = 4563}
}

local undersconfig = colorunder[item.uid]
local player = Player(cid)
    if getPlayerStorageValue(cid, undersconfig.storage) < 1 then
        player:teleportTo(undersconfig.newPos)
        doCreatureSay(cid, "Muahahaha!...", TALKTYPE_ORANGE_1)
        if getGlobalStorageValue(undersconfig.storage) < 1 then
            setGlobalStorageValue(undersconfig.storage, 1)
            Game.createMonster(undersconfig.creature, undersconfig.creaturepos)
        end
    else
        doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "The cave looks bad, you can't pass there any more.")
        return true
    end
return true
end
And it worked without problems. I think the metatables that you said is only if you need them. I saw some scripts that it doesnt have those metatables and works fine!. The order of them i dont think is important, because sometimes i put it in different order and worked fine, except by the cid, this always i put it at the beginning. Anyway, thanks for the info.
 
But i put the code:
Code:
function onUse(cid, item, fromPosition, toPosition, itemEx)

local colorunder = {
[4560] = {newPos = {x = 246, y = 116, z = 11}, creature = "Red Undergrounder", creaturepos = {x = 241, y = 116, z = 11}, storage = 4560},
[4561] = {newPos = {x = 283, y = 116, z = 11}, creature = "Green Undergrounder", creaturepos = {x = 277, y = 116, z = 11}, storage = 4561},
[4562] = {newPos = {x = 312, y = 116, z = 11}, creature = "Yellow Undergrounder", creaturepos = {x = 304, y = 116, z = 11}, storage = 4562},
[4563] = {newPos = {x = 360, y = 116, z = 11}, creature = "Blue Undergrounder", creaturepos = {x = 354, y = 113, z = 11}, storage = 4563}
}

local undersconfig = colorunder[item.uid]
local player = Player(cid)
    if getPlayerStorageValue(cid, undersconfig.storage) < 1 then
        player:teleportTo(undersconfig.newPos)
        doCreatureSay(cid, "Muahahaha!...", TALKTYPE_ORANGE_1)
        if getGlobalStorageValue(undersconfig.storage) < 1 then
            setGlobalStorageValue(undersconfig.storage, 1)
            Game.createMonster(undersconfig.creature, undersconfig.creaturepos)
        end
    else
        doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "The cave looks bad, you can't pass there any more.")
        return true
    end
return true
end
And it worked without problems. I think the metatables that you said is only if you need them. I saw some scripts that it doesnt have those metatables and works fine!. The order of them i dont think is important, because sometimes i put it in different order and worked fine, except by the cid, this always i put it at the beginning. Anyway, thanks for the info.
The order is very important. cid, item, fromPosition, etc. are only variable names for the arguments. When onUse is called, it is passed arguments. Because of the way onUse works in the engine, it receives a player object (or cid), then an item object, then the position the item was used from, then the target Thing (creature, item, etc.), then the position of the target, then whether it was used from a hotkey or not. It doesn't matter what they're called but it does matter the order. Because if you put cid, fromPosition, item then fromPosition is the second argument which is an item object because that's what the function is passed. In a language like c++ where the arguments must have defined types, you would end up with a different story by switching them around, but because lua doesn't require defined types for the arguments, you could name them like so: onUse(cat, dog, bird, moon, manbearpig) and it will still work because it's just the order they're passed in, you just call dog.actionid instead of item.actionid. While you're partially correct that it doesn't matter in this case, that's because you aren't using them. If you needed itemEx/target, you would be calling itemEx as an item while in your code it's actually a position because of the order. It's better practice to just have them in the correct order at all times otherwise when you actually need to use one of them, it's in the right place.

As for using metatables, you don't HAVE to use them, it will work fine because of compat.lua acting as a compatibility system, allowing you to use legacy functions as if they were the new ones (the legacy function simply calls the new one)
The only reason it's a good idea to use them is because that's the new standard for TFS 1.x and if you continue using older code you'll eventually run into issues with compatibility and you'll also be limited if the older functions aren't able to use certain new functionality. Plus you used player:teleportTo which is a metamethod, and Game.createMonster which is sort of a metamethod (it's new at least) but then also older things like getPlayerStorageValue. I just modified the code to keep it all consistent, it's not really a necessity, just good practice.
 
There is no such thing as a legacy function.. k thanks bye :)

This is not how a rational discussion works. Can you refer to any source from which you can base the following claim: "there is no such thing as a legacy function"?

Because I can find a lot of them:
"The term can also mean code inserted into modern software for the purpose of maintaining an older or previously supported feature", "source code inherited from an older version of the software" Reference.
"While this term may indicate that some engineers may feel that a system is out of date, a legacy system may continue to be used for a variety of reasons. It may simply be that the system still provides for the users' needs." Reference.

And if Wikipedia isn't enough for you, this is the definition by Michael Feathers:
"To me, legacy code is simply code without tests. " Reference. (page xvi)

Who is Michael Feathers?
"Internationally recognized software developer [...] Feathers, an expert developer with more than 20 years of experience, is the author of "Working Effectively with Legacy Code" and an active leader in the Agile software development community. [...] He developed CPPUnit, an open source C++ port of the JUnit testing framework; is a regular speaker at software conferences around the world; and has chaired the Codefest event at three Object-Oriented Programming, Systems, Languages and Applications (OOPSLA) conferences."

Can you explain what are all these people talking about? Perhaps the entire world is delirious.
Stack Overflow on legacy code.

Even Roberto Ierusalimschy mentions legacy code in this paper. (topic 3.1 DEL)
 
This is not how a rational discussion works. Can you refer to any source from which you can base the following claim: "there is no such thing as a legacy function"?

Because I can find a lot of them:
"The term can also mean code inserted into modern software for the purpose of maintaining an older or previously supported feature", "source code inherited from an older version of the software" Reference.
"While this term may indicate that some engineers may feel that a system is out of date, a legacy system may continue to be used for a variety of reasons. It may simply be that the system still provides for the users' needs." Reference.

And if Wikipedia isn't enough for you, this is the definition by Michael Feathers:
"To me, legacy code is simply code without tests. " Reference. (page xvi)

Who is Michael Feathers?
"Internationally recognized software developer [...] Feathers, an expert developer with more than 20 years of experience, is the author of "Working Effectively with Legacy Code" and an active leader in the Agile software development community. [...] He developed CPPUnit, an open source C++ port of the JUnit testing framework; is a regular speaker at software conferences around the world; and has chaired the Codefest event at three Object-Oriented Programming, Systems, Languages and Applications (OOPSLA) conferences."

Can you explain what are all these people talking about? Perhaps the entire world is delirious.
Stack Overflow on legacy code.

Even Roberto Ierusalimschy mentions legacy code in this paper. (topic 3.1 DEL)
Quote and reference whatever you like, you're talking apples and oranges here, half these people don't even know that there is no difference in scripting of any distro that has come out.. hell they think tfs is a programming language when it isn't its just a frame work.

Half you people are brain dead.. your a waste of text and my precious time.
 
Quote and reference whatever you like, you're talking apples and oranges here, half these people don't even know that there is no difference in scripting of any distro that has come out.. hell they think tfs is a programming language when it isn't its just a frame work.

Half you people are brain dead.. your a waste of text and my precious time.

I have a good link for you:
https://en.wikipedia.org/wiki/Wikipedia:Admitting_you're_wrong
 
Back
Top