• 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!
  • 2026 staff recruitment is open! Check it out and consider applying!

Solved Problem with a Custom NPC Need Help ASAP

Tyson12302

New Member
Joined
Aug 6, 2014
Messages
264
Reaction score
4
I've made a donator NPC that lets you buy from the shop ingame rather than on the website. Heres the code
[12/06/2015 21:54:35] [Error - LuaScriptInterface::loadFile] data/npc/scripts/donations.lua:24: '}' expected (to close '{' at line 21) near '['
[12/06/2015 21:54:35] [Warning - NpcScript::NpcScript] Cannot load script: data/npc/scripts/donations.lua
[12/06/2015 21:54:35] data/npc/scripts/donations.lua:24: '}' expected (to close '{' at line 21) near '['

Heres the code
Code:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState, xmsg = {}, {}

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

local function getPremiumPoints(cid)
    local res = db.getResult('select `points` from znote_accounts where name = \''..getPlayerAccount(cid)..'\'')
    if(res:getID() == -1) then
       return 0
    end
    local ret = res:getDataInt("points")
    res:free()
    return tonumber(ret)
end

local items = {
    ["Crystal Coin"] = {points = 10, itemid = 2160},  
    ["Soft Boots"] = {points = 20, itemid = 2640}
    ["Firewalker Boots"] = {points = 100, itemid = 9932}
    ["Demon Legs"] = {points = 15, itemid = 2495}
    ["Koshei's Ancient Amulet"] = {points = 30, itemid = 8266}
    ["Addon Doll"] = {points = 50, itemid = 8982}
    ["Power Sword"] = {points = 80, itemid = 2390}
    ["Stamina Doll"] = {points = 20, itemid = 9693}
}

function creatureSayCallback(cid, type, msg)
    if not npcHandler:isFocused(cid) then
        return false
    end

    local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid

    local x = items[msg:lower()]

    if msgcontains(msg, 'buy') then
        selfSay('Which donate item would you like to buy?', cid)
        talkState[talkUser] = 2
    elseif x and talkState[talkUser] >= 1 then
        selfSay('Do you want to buy 1 '..msg..' for '..x.points..' shop points?', cid)
        xmsg[cid] = msg
        talkState[talkUser] = 3
    elseif msgcontains(msg, 'yes') and talkState[talkUser] == 3 then
        x = items[xmsg[cid]:lower()]
        if getPremiumPoints(cid) >= x.points then
            selfSay('Here you are, have fun with it.', cid)
             doPlayerAddItem(cid, x.itemid, 1)
             db.executeQuery("UPDATE `znote_accounts` SET `points` = `points` + " .. points .. " where id = " .. getPlayerAccountId(cid) .. ";")
            talkState[talkUser] = 1
        else
            selfSay('You don\'t have enough points.', cid)
            talkState[talkUser] = 1
        end
    elseif msgcontains(msg, 'list') then
        text = 'Donation Items\n'
        for i, x in pairs(items) do
                text = text .. "\n" .. i .. " - "..x.points.." points"
        end
        doShowTextDialog(cid, 7391, "" .. text)
        talkState[talkUser] = 1
    elseif talkState[talkUser] == 2 then
        selfSay('You can\'t buy this item from me, look in the {list} which items you can buy.', cid)
    else
        selfSay('What? I don\'t understand what you mean with '..msg..'.', cid)
    end
    return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
By made you mean you found it here on OTLand? Because anyone who made this script would see the issue instantly since it's such an easy error.
 
Code:
local items = {
    ["Crystal Coin"] = {points = 10, itemid = 2160}, 
    ["Soft Boots"] = {points = 20, itemid = 2640},
    ["Firewalker Boots"] = {points = 100, itemid = 9932},
    ["Demon Legs"] = {points = 15, itemid = 2495},
    ["Koshei's Ancient Amulet"] = {points = 30, itemid = 8266},
    ["Addon Doll"] = {points = 50, itemid = 8982},
    ["Power Sword"] = {points = 80, itemid = 2390},
    ["Stamina Doll"] = {points = 20, itemid = 9693},
}
 
Code:
local items = {
    ["Crystal Coin"] = {points = 10, itemid = 2160},
    ["Soft Boots"] = {points = 20, itemid = 2640},
    ["Firewalker Boots"] = {points = 100, itemid = 9932},
    ["Demon Legs"] = {points = 15, itemid = 2495},
    ["Koshei's Ancient Amulet"] = {points = 30, itemid = 8266},
    ["Addon Doll"] = {points = 50, itemid = 8982},
    ["Power Sword"] = {points = 80, itemid = 2390},
    ["Stamina Doll"] = {points = 20, itemid = 9693},
}
Gotta remove that last ,
 
Aight. Not sure if the last , makes this error but when i ask the NPC to buy a item he says "22:29 Alfonzo: You can't buy this item from me, look in the list which items you can buy." The item is 100% on the list
 
Bump! I changed around the script and it now looks like this. Whenever i accept the item it says to buy more points when i already have enough on the website. Please help
Code:
local focuses = {}
local function isFocused(cid)
for i, v in pairs(focuses) do
if(v == cid) then
return true
end
end
return false
end

local function addFocus(cid)
if(not isFocused(cid)) then
table.insert(focuses, cid)
end
end
local function removeFocus(cid)
for i, v in pairs(focuses) do
if(v == cid) then
table.remove(focuses, i)
break
end
end
end
local function lookAtFocus()
for i, v in pairs(focuses) do
if(isPlayer(v)) then
doNpcSetCreatureFocus(v)
return
end
end
doNpcSetCreatureFocus(0)
end

local itemWindow = {

{id=2640, subType=0, buy=20, sell=0, name="Soft Boots", Bpoints = 20, Spoints = 0},
{id=9932, subType=0, buy=100, sell=0, name="Firewalker Boots", Bpoints = 100, Spoints = 0}



}

--{id=5785, subType=0, buy=1, sell=0, name="10P", Bpoints = 10, Spoints = 5},
--{id=5785, subType=0, buy=0, sell=1, name="5P", Bpoints = 10, Spoints = 5}

local items = {}
for _, item in ipairs(itemWindow) do
items[item.id] = {
buyPrice = item.buy,
sellPrice = item.sell,
subType = item.subType,
realName = item.name,
Bpoints = item.Bpoints or 0,
Spoints = item.Spoints or 0
}
end

local function getPlayerMoney(cid)
return getAccountPremiumPoints(cid)
end

local onBuy = function(cid, item, subType, amount, ignoreCap, inBackpacks)
if(items[item] == nil) then
selfSay("Ehm.. sorry... this shouldn't be there, I'm not selling it.", cid)
return
end

if(getPlayerMoney(cid) >= amount * items[item].Bpoints) then
if(getPlayerFreeCap(cid) >= getItemWeightById(item,amount)) then
local new_item = doCreateItemEx(item, amount)
local received_item = doPlayerAddItemEx(cid, new_item)
if received_item == RETURNVALUE_NOERROR then
selfSay("Thanks for the money!", cid)
doAccountRemovePremiumPoints(cid, amount * items[item].Bpoints)
else
selfSay("You have no space for this item!", cid)
end
else
selfSay("You can't carry this!", cid)
end
else
selfSay("Buy more premium points at {www.neuofia.zapto.org}", cid)
end
end

local onSell = function(cid, item, subType, amount, ignoreCap, inBackpacks)
if(items[item] == nil) then
selfSay("Ehm.. sorry... this shouldn't be there, I'm not buying it.", cid)
end

if(subType < 1) then
subType = -1
end
if(doPlayerRemoveItem(cid, item, amount, subType)) then
doAccountAddPremiumPoints(cid, items[item].Spoints * amount)
selfSay("Here you are.", cid)
else
selfSay("No item, no deal.", cid)
end
end

function onCreatureAppear(cid)
end

function onCreatureDisappear(cid)
if(isFocused(cid)) then
selfSay("Hmph!")
removeFocus(cid)
if(isPlayer(cid)) then --Be sure he's online
closeShopWindow(cid)
end
end
end

function onCreatureSay(cid, type, msg)
if((msg == "hi") and not (isFocused(cid))) then
selfSay("Welcome, ".. getCreatureName(cid) ..".", cid, true)
selfSay("Do you want to see my {wares}?", cid)
addFocus(cid)
elseif((isFocused(cid)) and (msg == "wares" or msg == "trade")) then
selfSay("Pretty nice, right?", cid)
openShopWindow(cid, itemWindow, onBuy, onSell)
elseif((isFocused(cid)) and (msg == "bye" or msg == "goodbye" or msg == "cya")) then
selfSay("Goodbye!", cid, true)
closeShopWindow(cid)
removeFocus(cid)
end
end

function onPlayerCloseChannel(cid)
if(isFocused(cid)) then
selfSay("Hmph!")
closeShopWindow(cid)
removeFocus(cid)
end
end

function onPlayerEndTrade(cid)
selfSay("It was a pleasure doing business with you.", cid)
end

function onThink()
for i, focus in pairs(focuses) do
if(not isCreature(focus)) then
removeFocus(focus)
else
local distance = getDistanceTo(focus) or -1
if((distance > 4) or (distance == -1)) then
selfSay("Hmph!")
closeShopWindow(focus)
removeFocus(focus)
end
end
end
lookAtFocus()
end

Heres the 050-function
Code:
function getAccountPremiumPoints(cid)
local res = db.getResult('SELECT points FROM znote_accounts WHERE id = '..getPlayerAccountId(cid))
if(res:getID() == -1) then
return 0
end
local ret = res:getDataInt("points")
res:free()
return tonumber(ret)
end

function doAccountAddPremiumPoints(cid, count)
return db.executeQuery("UPDATE `znote_accounts` SET `points` = '".. getAccountPremiumPoints(cid) + count .."' WHERE `id` ='"..getPlayerAccount(cid).."'")
end

function doAccountRemovePremiumPoints(cid, count)
return db.executeQuery("UPDATE `znote_accounts` SET `points` = '".. getAccountPremiumPoints(cid) - count .."' WHERE `id` ='"..getPlayerAccount(cid).."'")
end
 
before or after
Code:
selfSay("Buy more premium points at {www.neuofia.zapto.org}", cid)
put
Code:
print(getPlayerMoney(cid), amount * items[item].Bpoints)
it'll tell you what's going on.
 
Is this fine?
Code:
if(getPlayerMoney(cid) >= amount * items[item].Bpoints) then
if(getPlayerFreeCap(cid) >= getItemWeightById(item,amount)) then
local new_item = doCreateItemEx(item, amount)
local received_item = doPlayerAddItemEx(cid, new_item)
if received_item == RETURNVALUE_NOERROR then
selfSay("Thanks for the money!", cid)
doAccountRemovePremiumPoints(cid, amount * items[item].Bpoints)
else
selfSay("You have no space for this item!", cid)
end
else
selfSay("You can't carry this!", cid)
end
else
print(getPlayerMoney(cid), amount * items[item].Bpoints)
selfSay("Buy more premium points at {www.neuofia.zapto.org}", cid)
end
end
 
Code:
local x = items[msg:lower()]
This means it will remove the capitals from the message, so write the names in the table without capitals.
 
Code:
local x = items[msg:lower()]
This means it will remove the capitals from the message, so write the names in the table without capitals.
That fixed the problem, now he says Do you want to buy "item" for x points" when i say see. he says 216:01 Alfonzo: You don't have enough points." But i have alot of points on the website. Please help
 
Do what I said and post what comes up in the console.
The thing is that nothing comes up in the Console when i do that. I checked some other thread which had a fixed version but whenever i load my server i get a error saying function argument expected near ':'. Heres my new script.
Code:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}

function onCreatureAppear(cid) npcHandler:eek:nCreatureAppear(cid) end
function onCreatureDisappear(cid) npcHandler:eek:nCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg) npcHandler:eek:nCreatureSay(cid, type, msg) end
function onThink() npcHandler:eek:nThink() end

local function getPremiumPoints(cid)
local res = db.getResult('SELECT points FROM znote_accounts WHERE account_id = '..getPlayerAccountId(cid))
if(res:getID() == -1) then
return 0
end
local ret = res:getDataInt("points")
res:free()
return tonumber(ret)
end

function creatureSayCallback(cid, type, msg)
if(not npcHandler:isFocused(cid)) then
return false
end

local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid

local items = {
    ["crystal coin"] = {points = 10, itemid = 2160},  
    ["soft boots"] = {points = 20, itemid = 2640},
    ["firewalker boots"] = {points = 100, itemid = 9932},
    ["demon legs"] = {points = 15, itemid = 2495},
    ["koshei's ancient amulet"] = {points = 30, itemid = 8266},
    ["addon doll"] = {points = 50, itemid = 8982},
    ["power sword"] = {points = 80, itemid = 2390},
    ["stamina doll"] = {points = 20, itemid = 9693}
}

local function addCptl(first, rest)
return first:upper()..rest:lower()
end

local x = items[msg:gsub("(%a)([%w_']*)", addCptl)]

local buy = (msgcontains(msg, 'buy'))
if buy then
selfSay('Which donate item would you like to buy?', cid)
talkState[talkUser] = 2
end

if x and talkState[talkUser] >= 1 then 
selfSay('Do you want to buy 1 '..msg..' for '..x.points..' premium points?', cid)
xmsg = msg
talkState[talkUser] = 3
end
local agree = (msgcontains(msg, 'yes'))
if agree and talkState[talkUser] == 3 then 
x = items[xmsg:gsub("(%a)([%w_']*)", addCptl)]
if getPremiumPoints(cid) >= x.points then
selfSay('Here you are, have fun with it.', cid)
doPlayerAddItem(cid, x.itemid, 1)
db.executeQuery('UPDATE znote_accounts SET points=points-'..x.points..' WHERE account_id=' .. getPlayerAccountId(cid))
talkState[talkUser] = 1
else
selfSay('You don\'t have enough points.', cid)
talkState[talkUser] = 1
end
end

local list = (msgcontains(msg, 'list'))
if list then
text = 'Donation Items\n'
for i, x in pairs(items) do
text = text .. "\n" .. i .. " - "..x.points.." points"
end
doShowTextDialog(cid, 7391, "" .. text)
talkState[talkUser] = 1
end

if not x and not list and not buy and not agree and talkState[talkUser] == 2 then
selfSay('You can\'t buy this item from me, look in the {list} which items you can buy.', cid)
elseif not x and not list and not buy and not agree and talkState[talkUser] ~= 2 then
selfSay('What? I don\'t understand what you mean with '..msg..'.', cid)
end
return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
The thing is that nothing comes up in the Console when i do that. I checked some other thread which had a fixed version but whenever i load my server i get a error saying function argument expected near ':'. Heres my new script.
Code:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}

function onCreatureAppear(cid) npcHandler:eek:nCreatureAppear(cid) end
function onCreatureDisappear(cid) npcHandler:eek:nCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg) npcHandler:eek:nCreatureSay(cid, type, msg) end
function onThink() npcHandler:eek:nThink() end

local function getPremiumPoints(cid)
local res = db.getResult('SELECT points FROM znote_accounts WHERE account_id = '..getPlayerAccountId(cid))
if(res:getID() == -1) then
return 0
end
local ret = res:getDataInt("points")
res:free()
return tonumber(ret)
end

function creatureSayCallback(cid, type, msg)
if(not npcHandler:isFocused(cid)) then
return false
end

local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid

local items = {
    ["crystal coin"] = {points = 10, itemid = 2160}, 
    ["soft boots"] = {points = 20, itemid = 2640},
    ["firewalker boots"] = {points = 100, itemid = 9932},
    ["demon legs"] = {points = 15, itemid = 2495},
    ["koshei's ancient amulet"] = {points = 30, itemid = 8266},
    ["addon doll"] = {points = 50, itemid = 8982},
    ["power sword"] = {points = 80, itemid = 2390},
    ["stamina doll"] = {points = 20, itemid = 9693}
}

local function addCptl(first, rest)
return first:upper()..rest:lower()
end

local x = items[msg:gsub("(%a)([%w_']*)", addCptl)]

local buy = (msgcontains(msg, 'buy'))
if buy then
selfSay('Which donate item would you like to buy?', cid)
talkState[talkUser] = 2
end

if x and talkState[talkUser] >= 1 then
selfSay('Do you want to buy 1 '..msg..' for '..x.points..' premium points?', cid)
xmsg = msg
talkState[talkUser] = 3
end
local agree = (msgcontains(msg, 'yes'))
if agree and talkState[talkUser] == 3 then
x = items[xmsg:gsub("(%a)([%w_']*)", addCptl)]
if getPremiumPoints(cid) >= x.points then
selfSay('Here you are, have fun with it.', cid)
doPlayerAddItem(cid, x.itemid, 1)
db.executeQuery('UPDATE znote_accounts SET points=points-'..x.points..' WHERE account_id=' .. getPlayerAccountId(cid))
talkState[talkUser] = 1
else
selfSay('You don\'t have enough points.', cid)
talkState[talkUser] = 1
end
end

local list = (msgcontains(msg, 'list'))
if list then
text = 'Donation Items\n'
for i, x in pairs(items) do
text = text .. "\n" .. i .. " - "..x.points.." points"
end
doShowTextDialog(cid, 7391, "" .. text)
talkState[talkUser] = 1
end

if not x and not list and not buy and not agree and talkState[talkUser] == 2 then
selfSay('You can\'t buy this item from me, look in the {list} which items you can buy.', cid)
elseif not x and not list and not buy and not agree and talkState[talkUser] ~= 2 then
selfSay('What? I don\'t understand what you mean with '..msg..'.', cid)
end
return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
What line is the error
 
I found a console error. Here it is

[13/06/2015 17:44:53] [Error - Npc interface]
[13/06/2015 17:44:53] data/npc/scripts/donations.lua:onCreatureSay
[13/06/2015 17:44:53] Description:
[13/06/2015 17:44:53] data/npc/scripts/donations.lua:59: attempt to index local 'x' (a nil value)
[13/06/2015 17:44:53] stack traceback:
[13/06/2015 17:44:53] data/npc/scripts/donations.lua:59: in function 'callback'
[13/06/2015 17:44:53] data/npc/lib/npcsystem/npchandler.lua:383: in function 'onCreatureSay'
[13/06/2015 17:44:53] data/npc/scripts/donations.lua:8: in function <data/npc/scripts/donations.lua:8>

How do i fix this?
 
Back
Top