• 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 0.X [7.72] Craft System

potinho

Active Member
Joined
Oct 11, 2009
Messages
551
Solutions
14
Reaction score
47
Location
Brazil
Good morning guys, I am trying to deploy a craft system on my server with NPC, however when I choose the item I want to craft, it gives the following error on the console. If you can help me make it work.

NPC.XML
XML:
<?xml version="1.0"?>
<npc name="Drake" script="data/npc/scripts/drake.lua" walkinterval="50000" floorchange="0">
<health now="100" max="100"/>
<look type="129" head="95" body="116" legs="121" feet="115" addons="3"/>
<parameters>
<parameter key="message_greet" value="Hello |PLAYERNAME|. I can craft some {items} for you, but I need specific items to do them." />
</parameters>
</npc>

NPCSCRIPT.LUA
Lua:
function getItemsFromList(items)
    local str = ''
    if table.maxn(items) > 0 then
        for i = 1, table.maxn(items) do
            str = str .. items[i][2] .. ' ' .. getItemNameById(items[i][1])
            if i ~= table.maxn(items) then str = str .. ', ' 
            end 
        end 
    end
    return str
end
function doRemoveItemsFromList(cid,items)
    local count = 0
    if table.maxn(items) > 0 then
        for i = 1, table.maxn(items) do
            if getPlayerItemCount(cid,items[i][1]) >= items[i][2] then
            count = count + 1 end 
        end 
    end
    if count == table.maxn(items) then
        for i = 1, table.maxn(items) do doPlayerRemoveItem(cid,items[i][1],items[i][2]) end
    else 
        return false 
    end
    return true 
end    
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg) npcHandler:onCreatureSay(cid, type, msg) end
function onThink() npcHandler:onThink() end
function creatureSayCallback(cid, type, msg)
    if(not npcHandler:isFocused(cid)) then
        return false
    end
    local talkUser,msg = NPCHANDLER_CONVbehavior == CONVERSATION_DEFAULT and 0 or cid, msg:lower()
    local craft = {
                ["demon helmet"] = {reward = {{2493, 1}}, items = {{2173,1}, {8925,2}}},
                ["magic plate armor"] = {reward = {{2472, 1}}, items = {{2173,1}, {2160,10}, {2493,2}}}
                }
    
    if isInArray({"item","craft","itens","items", "iten"}, msg) then
        local text = ""
        for i, v in pairs(craft) do
            text = text .. " {"..i.."}, "
        end
        npcHandler:say("I can make " .. text .. " which one do you want?", cid)    
        talkState[talkUser] = 1 
    elseif talkState[talkUser] == 1 then
      ret = craft[msg] 
        if not ret then
             npcHandler:say("I am not crafting this item, perhaps I can consider your order later.", cid) return true
        end
        npcHandler:say("Oh, " .. msg .. " is a good choice. Let me see... I need " .. getItemsFromList(ret.items) .. ", do you have it?" , cid)        
         talkState[talkUser] = 2 
    elseif talkState[talkUser] == 2 and isInArray({"yes","yeah","sim","si"}, msg) then
      if not doRemoveItemsFromList(cid, ret.items) then
               talkState[talkUser] = 0 
            npcHandler:say("Sorry, but you don't have the items that I need.", cid) return true
        end
    for _, i_i in ipairs(ret.reward) do
        local item, amount = i_i[1], i_i[2]
        if isItemStackable(item) or amount == 1 then
             doPlayerAddItem(cid, item, amount)
        else
            for i = 1, amount do
                 doPlayerAddItem(cid, item, 1)
            end
        end
    end
        talkState[talkUser] = 0 
        doSendMagicEffect(getPlayerPosition(cid), math.random(28,30))
        npcHandler:say("Thank you very much! Here is your item as I promised.", cid) return true                    
    elseif msg == "no" then 
        selfSay("Ok... Bye!! Maybe on the next.", cid) 
        talkState[talkUser] = 0 
        npcHandler:releaseFocus(cid) 
    end
    return true
end
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

ERROR IN CONSOLE

[20/3/2021 11:8:29] [Error - NpcScript Interface]
[20/3/2021 11:8:29] data/npc/scripts/drake.lua:eek:nCreatureSay
[20/3/2021 11:8:29] Description:
[20/3/2021 11:8:29] data/lib/100-shortcut.lua:260: attempt to index a boolean value
[20/3/2021 11:8:29] stack traceback:
[20/3/2021 11:8:29] data/lib/100-shortcut.lua:260: in function 'getItemNameById'
[20/3/2021 11:8:29] [string "tasktabble = {..."]:232: in function 'getItemsFromList'
[20/3/2021 11:8:29] data/npc/scripts/drake.lua:57: in function 'callback'
[20/3/2021 11:8:29] data/npc/lib/npcsystem/npchandler.lua:363: in function 'onCreatureSay'
[20/3/2021 11:8:29] data/npc/scripts/drake.lua:33: in function <data/npc/scripts/drake.lua:33>
 
Solution
I think this is because it's getting a nil value.

Probably because it can't find the items.

Probably because the local is inside of the callback..?

Idk...

Here's my suggestion.

Lua:
local craft = {
    ["demon helmet"] = {reward = {{2493, 1}}, items = {{2173,1}, {8925,2}}},
    ["magic plate armor"] = {reward = {{2472, 1}}, items = {{2173,1}, {2160,10}, {2493,2}}}
}
function getItemsFromList(items)
    local str = ''
    if table.maxn(items) > 0 then
        for i = 1, table.maxn(items) do
            str = str .. items[i][2] .. ' ' .. getItemNameById(items[i][1])
            if i ~= table.maxn(items) then str = str .. ', ' 
            end 
        end 
    end
    return str
end
function doRemoveItemsFromList(cid,items)
    local...

Xikini

I whore myself out for likes
Support Team
Joined
Nov 17, 2010
Messages
5,695
Solutions
407
Reaction score
3,803
I think this is because it's getting a nil value.

Probably because it can't find the items.

Probably because the local is inside of the callback..?

Idk...

Here's my suggestion.

Lua:
local craft = {
    ["demon helmet"] = {reward = {{2493, 1}}, items = {{2173,1}, {8925,2}}},
    ["magic plate armor"] = {reward = {{2472, 1}}, items = {{2173,1}, {2160,10}, {2493,2}}}
}
function getItemsFromList(items)
    local str = ''
    if table.maxn(items) > 0 then
        for i = 1, table.maxn(items) do
            str = str .. items[i][2] .. ' ' .. getItemNameById(items[i][1])
            if i ~= table.maxn(items) then str = str .. ', ' 
            end 
        end 
    end
    return str
end
function doRemoveItemsFromList(cid,items)
    local count = 0
    if table.maxn(items) > 0 then
        for i = 1, table.maxn(items) do
            if getPlayerItemCount(cid,items[i][1]) >= items[i][2] then
            count = count + 1 end 
        end 
    end
    if count == table.maxn(items) then
        for i = 1, table.maxn(items) do doPlayerRemoveItem(cid,items[i][1],items[i][2]) end
    else 
        return false 
    end
    return true 
end    
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg) npcHandler:onCreatureSay(cid, type, msg) end
function onThink() npcHandler:onThink() end
function creatureSayCallback(cid, type, msg)
    if not npcHandler:isFocused(cid) then
        return false
    end
    local talkUser,msg = NPCHANDLER_CONVbehavior == CONVERSATION_DEFAULT and 0 or cid, msg:lower()
    
    if isInArray({"item","craft","itens","items", "iten"}, msg) then
        local text = ""
        for i, v in pairs(craft) do
            text = text .. " {"..i.."}, "
        end
        npcHandler:say("I can make " .. text .. " which one do you want?", cid)    
        talkState[talkUser] = 1 
    elseif talkState[talkUser] == 1 then
        ret = craft[msg] 
        if not ret then
            npcHandler:say("I am not crafting this item, perhaps I can consider your order later.", cid) return true
        end
        npcHandler:say("Oh, " .. msg .. " is a good choice. Let me see... I need " .. getItemsFromList(ret.items) .. ", do you have it?" , cid)        
        talkState[talkUser] = 2 
    elseif talkState[talkUser] == 2 and isInArray({"yes","yeah","sim","si"}, msg) then
        if not doRemoveItemsFromList(cid, ret.items) then
                talkState[talkUser] = 0 
                npcHandler:say("Sorry, but you don't have the items that I need.", cid) return true
            end
        for _, i_i in ipairs(ret.reward) do
            local item, amount = i_i[1], i_i[2]
            if isItemStackable(item) or amount == 1 then
                doPlayerAddItem(cid, item, amount)
            else
                for i = 1, amount do
                    doPlayerAddItem(cid, item, 1)
                end
            end
        end
        talkState[talkUser] = 0 
        doSendMagicEffect(getPlayerPosition(cid), math.random(28,30))
        npcHandler:say("Thank you very much! Here is your item as I promised.", cid) return true                    
    elseif msg == "no" then 
        selfSay("Ok... Bye!! Maybe on the next.", cid) 
        talkState[talkUser] = 0 
        npcHandler:releaseFocus(cid) 
    end
    return true
end
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Solution
Top