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

Lua Npc Call DB Table to Sell

alejandro762

Well-Known Member
Joined
Sep 6, 2021
Messages
225
Reaction score
63
Hello,

I Wanted to know if is possible to call a table DB value (numbers) on a Npc in order to sell Items for this currency from Db.
We want change if player:additem into calling DB table `account` WHERE `coins` , following amount* itemsTable[item].sell, amount* itemsTable[item].sell) then

if player:addItem(38840, amount* itemsTable[item].sell, amount* itemsTable[item].sell) then return player:sendTextMessage(MESSAGE_TRADE, "Sell "..amount.."x "..itemsTable[item].name.." for "..itemsTable[item].name..".") end

This is the part, buy/sell, changing getCurrency for example to get local dbTable = db.query.. But is giving an error "player" nil value.

Lua:
local function onBuy(cid, item, subType, amount, ignoreCap, inBackpacks)
    local player = Player(cid)
    local itemsTable = setNewTradeTable(shop)
    if not ignoreCap and player:getFreeCapacity() < ItemType(itemsTable[item].id):getWeight(amount) then
        return player:sendTextMessage(MESSAGE_INFO_DESCR, "You don't have enough cap.")
    end
    if itemsTable[item].buy then
        if player:removeItem(Npc():getCurrency(), amount * itemsTable[item].buy) then
            if amount > 1 then
                currencyName = ItemType(Npc():getCurrency()):getPluralName():lower()
            else
                currencyName = ItemType(Npc():getCurrency()):getName():lower()
            end
            player:addItem(itemsTable[item].id, amount)
            return player:sendTextMessage(MESSAGE_INFO_DESCR,
                        "Bought "..amount.."x "..itemsTable[item].name.." for "..itemsTable[item].buy * amount.." "..currencyName..".")
        else
            return player:sendTextMessage(MESSAGE_INFO_DESCR, "You don't have enough "..currencyName..".")
        end
    end
end

local function onSell(cid, item, subType, amount, ignoreCap, inBackpacks)
    local player = Player(cid)
    local itemsTable = setNewTradeTable(shop)
    if not ignoreCap and player:getFreeCapacity() < ItemType(itemsTable[item].id):getWeight(amount) then
        return player:sendTextMessage(MESSAGE_FAILURE, "You don't have enough cap.")
        end
        if player:removeItem(item, amount, 1, amount* itemsTable[item].sell) then
            end
        if player:addItem(38840, amount* itemsTable[item].sell, amount* itemsTable[item].sell) then
            return player:sendTextMessage(MESSAGE_TRADE,
                        "Sell "..amount.."x "..itemsTable[item].name.." for "..itemsTable[item].name..".")
end
return true
end

we don't know how to use db.query and manage to try it working,
If someone can explain me please,

Thanks
 
Last edited:
I Try like this, but get a boolean value,
what we didn't know is the function for the player, if player:removeItem ? :/

The DB query works, but showing an error "out of range value for column 'coins'.
But it works because from 1 coin now got 0 coins, but it doesnt give the item,

Lua:
local shop = {
    {id=10159, buy=1, sell=1, name='Helmet'},
}
local function setNewTradeTable(table)
    local items, item = {}
    for i = 1, #table do
        item = table[i]
        items[item.id] = {id = item.id, buy = item.buy, sell = item.sell, subType = 0, name = item.name}
    end
    return items
end
local function onBuy(cid, item, subType, amount, ignoreCap, inBackpacks)
    local player = Player(cid)
    local itemsTable = setNewTradeTable(shop)
    local getCurrencyT = db.query("UPDATE `accounts` SET `coins` = `coins` - '" ..itemsTable[item].sell.. "' WHERE `id` = '" .. player:getAccountId() .. "';")
    if not ignoreCap and player:getFreeCapacity() < ItemType(itemsTable[item].id):getWeight(amount) then
        return player:sendTextMessage(MESSAGE_INFO_DESCR, "You don't have enough cap.")
    end
    if itemsTable[item].buy then
        if player:remove(getCurrencyT(), amount * itemsTable[item].buy) then
            if amount > 1 then
                currencyName = ItemType(getCurrencyT):getPluralName():lower()
            else
                currencyName = ItemType(getCurrencyT):getName():lower()
            end
            player:addItem(itemsTable[item].id, amount)
            return player:sendTextMessage(MESSAGE_INFO_DESCR,
                        "Bought "..amount.."x "..itemsTable[item].name.." for "..itemsTable[item].buy * amount.." "..currencyName..".")
        else
            return player:sendTextMessage(MESSAGE_INFO_DESCR, "You don't have enough "..currencyName..".")
        end
    end
end

Did we need maybe to add on compat.lua a function like: (doesn't require src changes ? )
Then use if player:getPlayerTableDB(getCurrencyT(), amount * itemsTable[item].buy) then
Code:
function getPlayerTableDB(name)
    local player = Player(coins)
    if player then
        return player:getTableDB()
    end

    local resultId = db.storeQuery("SELECT `account` FROM `players` WHERE `coins` = " .. db.escapeString(coins))
    if resultTableDB ~= false then
        local TableDB= result.getDataInt(resultId, "account")
        result.free(resultId)
        return TableDB
    end
    return 0
end
 
Last edited:
Hello,

I Wanted to know if is possible to call a table DB value (numbers) on a Npc in order to sell Items for this currency from Db.
We want change if player:additem into calling DB table `account` WHERE `coins` , following amount* itemsTable[item].sell, amount* itemsTable[item].sell) then

if player:addItem(38840, amount* itemsTable[item].sell, amount* itemsTable[item].sell) then return player:sendTextMessage(MESSAGE_TRADE, "Sell "..amount.."x "..itemsTable[item].name.." for "..itemsTable[item].name..".") end

This is the part, buy/sell, changing getCurrency for example to get local dbTable = db.query.. But is giving an error "player" nil value.

Lua:
local function onBuy(cid, item, subType, amount, ignoreCap, inBackpacks)
    local player = Player(cid)
    local itemsTable = setNewTradeTable(shop)
    if not ignoreCap and player:getFreeCapacity() < ItemType(itemsTable[item].id):getWeight(amount) then
        return player:sendTextMessage(MESSAGE_INFO_DESCR, "You don't have enough cap.")
    end
    if itemsTable[item].buy then
        if player:removeItem(Npc():getCurrency(), amount * itemsTable[item].buy) then
            if amount > 1 then
                currencyName = ItemType(Npc():getCurrency()):getPluralName():lower()
            else
                currencyName = ItemType(Npc():getCurrency()):getName():lower()
            end
            player:addItem(itemsTable[item].id, amount)
            return player:sendTextMessage(MESSAGE_INFO_DESCR,
                        "Bought "..amount.."x "..itemsTable[item].name.." for "..itemsTable[item].buy * amount.." "..currencyName..".")
        else
            return player:sendTextMessage(MESSAGE_INFO_DESCR, "You don't have enough "..currencyName..".")
        end
    end
end

local function onSell(cid, item, subType, amount, ignoreCap, inBackpacks)
    local player = Player(cid)
    local itemsTable = setNewTradeTable(shop)
    if not ignoreCap and player:getFreeCapacity() < ItemType(itemsTable[item].id):getWeight(amount) then
        return player:sendTextMessage(MESSAGE_FAILURE, "You don't have enough cap.")
        end
        if player:removeItem(item, amount, 1, amount* itemsTable[item].sell) then
            end
        if player:addItem(38840, amount* itemsTable[item].sell, amount* itemsTable[item].sell) then
            return player:sendTextMessage(MESSAGE_TRADE,
                        "Sell "..amount.."x "..itemsTable[item].name.." for "..itemsTable[item].name..".")
end
return true
end

we don't know how to use db.query and manage to try it working,
If someone can explain me please,

Thanks
I don't get what you want, but if you want to buy and sell items for coins that are stored in database, just do the query needed to add and remove coins.

For exemple:

Lua:
------------ functions
local function playerGetCoins(player)
      return db.query("SELECT `coins` FROM `accounts` WHERE `id` = '" .. player:getAccountId() .. "';")
end

local function playerAddCoins(player, value)
      return db.query("UPDATE `accounts` SET `coins` = `coins` + '" .. value .. "' WHERE `id` = '" .. player:getAccountId() .. "';")
end

local function playerRemoveCoins(player, value)
      return db.query("UPDATE `accounts` SET `coins` = `coins` - '" .. value .. "' WHERE `id` = '" .. player:getAccountId() .. "';")
end
------------ end of functions

local function onBuy(cid, item, subType, amount, ignoreCap, inBackpacks)

local player = Player(cid)
local itemsTable = setNewTradeTable(shop)
if not ignoreCap and player:getFreeCapacity() < ItemType(itemsTable[item].id):getWeight(amount) then
     return player:sendTextMessage(MESSAGE_INFO_DESCR, "You don't have enough cap.")
end
if itemsTable[item].buy then
   if (playerGetCoins(player) >= (amount * itemsTable[item].buy)) then
       if amount > 1 then
          currencyName = ItemType(Npc():getCurrency()):getPluralName():lower()
        else
           currencyName = ItemType(Npc():getCurrency()):getName():lower()
       end
     player:addItem(itemsTable[item].id, amount)
     playerRemoveCoins(player, amount * itemsTable[item].buy)
     return player:sendTextMessage(MESSAGE_INFO_DESCR, "Bought "..amount.."x "..itemsTable[item].name.." for "..itemsTable[item].buy * amount.." "..currencyName..".")
   else
     return player:sendTextMessage(MESSAGE_INFO_DESCR, "You don't have enough "..currencyName..".")
   end
end
end

Something like that.
 
I don't get what you want, but if you want to buy and sell items for coins that are stored in database, just do the query needed to add and remove coins.

For exemple:

Lua:
------------ functions
local function playerGetCoins(player)
      return db.query("SELECT `coins` FROM `accounts` WHERE `id` = '" .. player:getAccountId() .. "';")
end

local function playerAddCoins(player, value)
      return db.query("UPDATE `accounts` SET `coins` = `coins` + '" .. value .. "' WHERE `id` = '" .. player:getAccountId() .. "';")
end

local function playerRemoveCoins(player, value)
      return db.query("UPDATE `accounts` SET `coins` = `coins` - '" .. value .. "' WHERE `id` = '" .. player:getAccountId() .. "';")
end
------------ end of functions

local function onBuy(cid, item, subType, amount, ignoreCap, inBackpacks)

local player = Player(cid)
local itemsTable = setNewTradeTable(shop)
if not ignoreCap and player:getFreeCapacity() < ItemType(itemsTable[item].id):getWeight(amount) then
     return player:sendTextMessage(MESSAGE_INFO_DESCR, "You don't have enough cap.")
end
if itemsTable[item].buy then
   if (playerGetCoins(player) >= (amount * itemsTable[item].buy)) then
       if amount > 1 then
          currencyName = ItemType(Npc():getCurrency()):getPluralName():lower()
        else
           currencyName = ItemType(Npc():getCurrency()):getName():lower()
       end
     player:addItem(itemsTable[item].id, amount)
     playerRemoveCoins(player, amount * itemsTable[item].buy)
     return player:sendTextMessage(MESSAGE_INFO_DESCR, "Bought "..amount.."x "..itemsTable[item].name.." for "..itemsTable[item].buy * amount.." "..currencyName..".")
   else
     return player:sendTextMessage(MESSAGE_INFO_DESCR, "You don't have enough "..currencyName..".")
   end
end
end

Something like that.
Oh, so is using a different function, my Bad. Sorry im learning slowly, i will try to write the function when i come back at house.
O will check also, because is reading currencyName = NPCs currency , and i wish remove that.
Thanks for explain.
 
Oh, so is using a different function, my Bad. Sorry im learning slowly, i will try to write the function when i come back at house.
O will check also, because is reading currencyName = NPCs currency , and i wish remove that.
Thanks for explain.
About that, this function that you want to delete is only getting the name of the currency.

If you dont want that, just delete:
Lua:
       if amount > 1 then
          currencyName = ItemType(Npc():getCurrency()):getPluralName():lower()
        else
           currencyName = ItemType(Npc():getCurrency()):getName():lower()
       end

and change where is
Code:
"..currencyName.."
to coin/coins or simply delete
 
About that, this function that you want to delete is only getting the name of the currency.

If you dont want that, just delete:
Lua:
       if amount > 1 then
          currencyName = ItemType(Npc():getCurrency()):getPluralName():lower()
        else
           currencyName = ItemType(Npc():getCurrency()):getName():lower()
       end

and change where is
Code:
"..currencyName.."
to coin/coins or simply delete

There is the full script,

Is not giving any error, Npc on buy=1, it doesn't give the opportunity to buy an item, it appears on 0, i cannot buy the 'helmet' for 1 tc.

Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

local shop = {
    {id=10159, buy=1, sell=1, name='Helmet'},

}

------------ functions
local function playerGetCoins(player)
      return db.query("SELECT `coins` FROM `accounts` WHERE `id` = '" .. player:getAccountId() .. "';")
end

local function playerAddCoins(player, value)
      return db.query("UPDATE `accounts` SET `coins` = `coins` + '" .. value .. "' WHERE `id` = '" .. player:getAccountId() .. "';")
end

local function playerRemoveCoins(player, value)
      return db.query("UPDATE `accounts` SET `coins` = `coins` - '" .. value .. "' WHERE `id` = '" .. player:getAccountId() .. "';")
end
------------ end of functions

local function setNewTradeTable(table)
    local items, item = {}
    for i = 1, #table do
        item = table[i]
        items[item.id] = {id = item.id, buy = item.buy, sell = item.sell, subType = 0, name = item.name}
    end
    return items
end
local function onBuy(cid, item, subType, amount, ignoreCap, inBackpacks)
local player = Player(cid)
local itemsTable = setNewTradeTable(shop)
if not ignoreCap and player:getFreeCapacity() < ItemType(itemsTable[item].id):getWeight(amount) then
     return player:sendTextMessage(MESSAGE_INFO_DESCR, "You don't have enough cap.")
end
if itemsTable[item].buy then
   if (playerGetCoins(player) >= (amount * itemsTable[item].buy)) then
     player:addItem(itemsTable[item].id, amount)
     playerRemoveCoins(player, amount * itemsTable[item].buy)
     return player:sendTextMessage(MESSAGE_INFO_DESCR, "Bought "..amount.."x "..itemsTable[item].name.." for "..itemsTable[item].buy * amount.." tc.")
   else
     return player:sendTextMessage(MESSAGE_INFO_DESCR, "You don't have enough tc.")
   end
end
end
local function onSell(cid, item, subType, amount, ignoreCap, inBackpacks)
    local player = Player(cid)
    local itemsTable = setNewTradeTable(shop)
    if not ignoreCap and player:getFreeCapacity() < ItemType(itemsTable[item].id):getWeight(amount) then
        return player:sendTextMessage(MESSAGE_FAILURE, "You don't have enough cap.")
        end
        if player:removeItem(item, amount, 1, amount* itemsTable[item].sell) then
            end
        if player:addItem(38840, amount* itemsTable[item].sell, amount* itemsTable[item].sell) then
            return player:sendTextMessage(MESSAGE_TRADE,
                        "Sell "..amount.."x "..itemsTable[item].name.." for "..itemsTable[item].name..".")
end
return true
end



local answerType = {}
local answerLevel = {}

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 greetCallback(cid)
    npcHandler.topic[cid] = 0
    return true
end

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

    local player = Player(cid)

   
   
    return true
end



local voices = { {text = 'Do you wish trade some items?!'} }
npcHandler:addModule(VoiceModule:new(voices))

npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus)
npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus)

npcHandler:setCallback(CALLBACK_GREET, greetCallback)
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Got it.
Isn't working because trade table needs a Currency. Servers currency are Gold Coin as default.
Without changing the code, under player:removeItem, adding playerRemoveCoins(player, 5) for example, it takes 1 gold coin, then it takes also 5 Tibia coins.
Is the only solution i found to make it work, since i think is not possible on trade table to do it without changing src.
Thanks anyway!
 
Got it.
Isn't working because trade table needs a Currency. Servers currency are Gold Coin as default.
Without changing the code, under player:removeItem, adding playerRemoveCoins(player, 5) for example, it takes 1 gold coin, then it takes also 5 Tibia coins.
Is the only solution i found to make it work, since i think is not possible on trade table to do it without changing src.
Thanks anyway!
you mean using trade? if it is, yes, then you will need other modifications because when you use "trade", the server recognizes gold as currency and not coins.
 
you mean using trade? if it is, yes, then you will need other modifications because when you use "trade", the server recognizes gold as currency and not coins.
Yeah i see on Npp source , and i know how to modify is similar as gold pouch easy to do It.

But is ok like this because i was wondering to use a storage to be able to TRADE but in this case it will require the currency (just one) like a special item in order to Trade. It will not remove the special items but yes the coins is Amazing.

Thanks again
 
Back
Top