Someone posted good idea for NPC. I tried to make this NPC.
Player can give this NPC items and set price for each item type.
Other player can come and say:
offer of Player Name - show offer of player with nick XX in 'trade' window
search Item Name - show 5 cheapest offers of item with name XX in form:
-----------------------------------
It's beat version for tests only. Work with TFS0.2pl16 (tibia 8.3) and my modified .exe file (fixed one bug with NPC trade window, but we must wait for official release of new TFS 0.2 with NPC system fixed).
NPC .xml file:
NPC .lua script:
In global.lua add functions:
My .exe file:
TFS83.exe
If you use your modified version of TFS 0.2 pl 16 engine, you must only replace your function (file npc.cpp):
With:
FOR TESTS ONLY
Player can give this NPC items and set price for each item type.
Other player can come and say:
offer of Player Name - show offer of player with nick XX in 'trade' window
search Item Name - show 5 cheapest offers of item with name XX in form:
All commands and how to use NPC say when player say "how to use":19:59 Cheapest offers of stone skin amulet:
50 gp (charges: 15) - Banatoorooo
1000000 gp (charges: 5) - Banatoorooo
19:59 GOD Gesior [150]: how to use
19:59 Shopper: What you want to do? Say {add my item to offer}, {get my item from offer}, {check how much money from items I have}, {get my cash from items}, {change price ofitem in offer}, {buy item of other player} or {search item}.
19:59 GOD Gesior [150]: add my item to offer
19:59 Shopper: First put your item in left hand (under BP slot), then say {add item xx} where xx is number of items that you want add to offer, then NPC will ask you for price, say{price yy}, where yy is price for 1 item.
-----------------------------------
It's beat version for tests only. Work with TFS0.2pl16 (tibia 8.3) and my modified .exe file (fixed one bug with NPC trade window, but we must wait for official release of new TFS 0.2 with NPC system fixed).
NPC .xml file:
PHP:
<?xml version="1.0" encoding="UTF-8"?>
<npc name="Shopper" script="data/npc/scripts/shopper.lua" walkinterval="2000" floorchange="0">
<health now="100" max="100"/>
<look type="290" head="39" body="122" legs="125" feet="57" addons="0"/>
<parameters />
</npc>
Code:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
shop_offers = {}
shop_last_item = {}
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
npcHandler:say('I don\'t understand. Ask me for {how to use} to get available actions.', cid)
end
function onBuyItemNPC(cid, itemid, subType, amount)
if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
npcHandler.talkStart[cid] = os.time()
else
npcHandler.talkStart = os.time()
end
local offers = shop_offers[cid]
local item = {id=0}
for i = 1, #offers do
print('test: ' .. offers[i].itemid .. ' = ' .. itemid .. ' : ' .. offers[i].subType .. ' = ' .. subType)
if itemid == offers[i].itemid and subType == offers[i].subType then
item = getItemWithId(offers[i].id)
item = getItemWithItemId(offers[i].name, offers[i].itemid, offers[i].subType)
end
end
if (not (item.id > 0)) then
npcHandler:say('This item is not available in this player offer.', cid)
return true
end
local amount2 = amount
if amount2 > item.count then
amount2 = item.count
end
if item.name == getCreatureName(cid) then
local boughtItems, i = addPlayerItemFromShop(cid, item.itemid, amount2, item.subType)
if(i < amount) then
if(i > 0) then
removeItemsFromOffer(item.name, item.itemid, item.subType, i)
if amount == amount2 then
npcHandler:say('Here you are your ' .. i .. ' of requested ' .. amount .. ' ' .. item.item_name .. ', because you do not have enought capacity for all.', cid)
else
npcHandler:say('Here you are your ' .. i .. ' of requested ' .. amount .. ' ' .. item.item_name .. ', because I do not have more your items of this type.', cid)
closeShopWindow(cid)
end
else
npcHandler:say('You do not have capacity for this item.', cid)
end
else
removeItemsFromOffer(item.name, item.itemid, item.subType, i)
npcHandler:say('Here you are your ' .. amount .. ' ' .. item.item_name .. '.', cid)
end
else
if (getPlayerMoney(cid) < amount * item.price) then
if(amount == 1) then
npcHandler:say(item.item_name .. ' cost ' .. item.price .. ' gp, you got only ' .. getPlayerMoney(cid) .. ' gp.', cid)
else
npcHandler:say(amount .. ' ' .. item.item_name ..'s cost ' .. amount * item.price .. ' gp, you got only ' .. getPlayerMoney(cid) .. ' gp.', cid)
end
return true
end
--print(amount2 .. "<<amount2 || " .. amount .. " < amount || count > " .. item.count)
local boughtItems, i = addPlayerItemFromShop(cid, item.itemid, amount2, item.subType)
if(i < amount) then
if(i > 0) then
removeItemsFromOffer(item.name, item.itemid, item.subType, i)
doPlayerRemoveMoney(cid, i * item.price)
setCash(name, getCash(name)+i * item.price)
if amount == amount2 then
npcHandler:say('Here you are ' .. i .. ' of requested ' .. amount .. ' ' .. item.item_name .. ' for ' .. i * item.price .. ' gp, because you do not have enought capacity for all.', cid)
else
npcHandler:say('Here you are ' .. i .. ' of requested ' .. amount .. ' ' .. item.item_name .. ' for ' .. i * item.price .. ' gp, because I do not have more for sell.', cid)
closeShopWindow(cid)
end
doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You bought " .. i .. "x " .. item.item_name .. ".")
else
npcHandler:say('You do not have capacity for this item.', cid)
end
else
removeItemsFromOffer(item.name, item.itemid, item.subType, i)
doPlayerRemoveMoney(cid, i * item.price)
setCash(name, getCash(name)+i * item.price)
npcHandler:say('Here you are ' .. amount .. ' ' .. item.item_name .. ' for ' .. i * item.price .. ' gp.', cid)
doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You bought " .. i .. "x " .. item.item_name .. ".")
end
end
return true
end
function onSellItemNPC(cid, itemid, subType, amount)
return true
end
function showOfferOfPlayerNPC(cid, message, keywords, parameters, node)
if(not npcHandler:isFocused(cid)) then
return false
end
local name = ''
if keywords[1] == 'my offer' or keywords[1] == 'get item' then
name = getCreatureName(cid)
npcHandler:say('You can take your items if you don\'t want sell them.', cid)
else
name = string.sub(message, 10)
npcHandler:say('Offer of ' .. name .. '.', cid)
end
local offer = getOfferOfPlayer(name)
shop_offers[cid] = offer
local itemWindow = {}
local item = {}
for i = 1, #offer do
if keywords[1] == 'my offer' or keywords[1] == 'get item' then
item = {id = offer[i].itemid, buy = 1, sell = 0, subType = offer[i].subType, name = offer[i].item_name .. "(" .. offer[i].count .. ")"}
else
item = {id = offer[i].itemid, buy = offer[i].price, sell = 0, subType = offer[i].subType, name = offer[i].item_name .. "(" .. offer[i].count .. ")"}
end
table.insert(itemWindow, item)
end
openShopWindow(cid, itemWindow, function(cid, itemid, subType, amount) onBuyItemNPC(cid, itemid, subType, amount) end, function(cid, itemid, subType, amount) onSellItemNPC(cid, itemid, subType, amount) end)
npcHandler:resetNpc()
return true
end
function showOfferOfItemNPC(cid, message, keywords, parameters, node)
if(not npcHandler:isFocused(cid)) then
return false
end
local item_name = string.sub(message, 8)
local offer = getOfferOfItem(item_name)
local msg = ''
if #offer == 0 then
msg = "Can\'t find offer of item with name >" .. item_name .. "<"
else
msg = "Cheapest offers of " .. item_name .. ":\n"
for i = 1, #offer do
if offer[i].subType > 0 then
msg = msg .. offer[i].price .. " gp (charges: " .. offer[i].subType .. ") - " .. offer[i].name
else
msg = msg .. offer[i].price .. " gp - " .. offer[i].name
end
if #offer ~= i then
msg = msg .. "\n"
end
end
end
doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, msg)
npcHandler:resetNpc()
return true
end
function addItemToOfferNPC(cid, message, keywords, parameters, node)
if(not npcHandler:isFocused(cid)) then
return false
end
local number = 0
for word in string.gmatch(tostring(message), "(%w+)") do
if tostring(tonumber(word)) == word then
number = tonumber(word)
end
end
if (parameters.setprice == true) then
local item_db = getItemWithItemId(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType)
if number < 1 then
number = 1
end
changePriceOfItem(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType, number)
item_db = getItemWithItemId(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType)
if item_db.subType > 0 then
npcHandler:say('Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' (charges: ' .. item_db.subType .. ') in offer, price for each is now ' .. item_db.price .. ' gp. Say {set price} to change price of items.', cid)
else
npcHandler:say('Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' in offer, price for each is now ' .. item_db.price .. ' gp. Say {set price} to change price of items.', cid)
end
shop_last_item[cid] = {}
npcHandler:resetNpc()
elseif (parameters.setprice == false) then
item_db = getItemWithItemId(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType)
npcHandler:say('Ok. I do not change price for ' .. getItemName(shop_last_item[cid].itemid) ..'. It is ' .. item_db.price .. ' gp/each now.', cid)
shop_last_item[cid] = {}
npcHandler:resetNpc()
else
local item = getPlayerSlotItem(cid, 5)
if (item.itemid == 0) then
npcHandler:say('Your left hand (under BP slot) is empty.', cid)
npcHandler:resetNpc()
return true
end
if (isItemContainer(item.itemid) == TRUE and getContainerItem(uid, 0).uid > 0) then
npcHandler:say('In your left hand (under BP slot) is not empty container. You can add to offer only item and empty containers.', cid)
npcHandler:resetNpc()
return true
end
if number < 1 then
number = 1
end
if (item.type > 0 and not(isItemStackable(item.itemid) == TRUE)) then
number = 1
doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'You can\'t sell more then one ' .. getItemName(item.itemid) .. ' (charges: ' .. item.type .. '). Sorry.')
end
local to_remove = number
shop_last_item[cid] = {itemid = item.itemid, subType = item.type}
if (number > getPlayerItemCount(cid, item.itemid)) then
number = getPlayerItemCount(cid, item.itemid)
end
if (isItemStackable(item.itemid) == TRUE) then
item.type = 0
end
if (number == 1) and (isItemStackable(item.itemid) == TRUE) then
doRemoveItem(item.uid, number)
elseif (number == 1) and not(isItemStackable(item.itemid) == TRUE) then
doRemoveItem(item.uid, 1)
else
doPlayerRemoveItem(cid, item.itemid, number)
end
addItemToOffer(getCreatureName(cid), item.itemid, item.type, number)
item_db = getItemWithItemId(getCreatureName(cid), item.itemid, item.type)
if item.type > 0 then
npcHandler:say('Added ' .. number .. ' ' .. getItemName(item.itemid) .. ' (charges: ' .. item.type .. ') to your offer. Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' (charges: ' .. item_db.subType .. ') in offer, price for each is ' .. item_db.price .. '. Do you want to change price? Say {no} or {price xxx}, where xxx is number of gp.', cid)
else
npcHandler:say('Added ' .. number .. ' ' .. getItemName(item.itemid) .. ' to your offer. Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' in offer, price for each is ' .. item_db.price .. '. Do you want to change price? Say {no} or {price xxx}, where xxx is number of gp.', cid)
end
end
return true
end
function setItemPriceNPC(cid, message, keywords, parameters, node)
if(not npcHandler:isFocused(cid)) then
return false
end
local number = 0
for word in string.gmatch(tostring(message), "(%w+)") do
if tostring(tonumber(word)) == word then
number = tonumber(word)
end
end
if (parameters.setprice == true) then
local item_db = getItemWithItemId(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType)
if number < 1 then
number = 1
end
changePriceOfItem(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType, number)
item_db = getItemWithItemId(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType)
if item_db.subType > 0 then
npcHandler:say('Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' (charges: ' .. item_db.subType .. ') in offer, price for each is now ' .. item_db.price .. ' gp. Say {set price} to change price of items.', cid)
else
npcHandler:say('Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' in offer, price for each is now ' .. item_db.price .. ' gp. Say {set price} to change price of items.', cid)
end
shop_last_item[cid] = {}
npcHandler:resetNpc()
else
if number > 0 then -- player said offer ID
local item_db = getItemWithId(number)
if item_db.id == 0 then
npcHandler:say('I don\'t know offer with ID >' .. number .. '<, say {set price} to view list of your items IDs.', cid)
npcHandler:resetNpc()
return true
end
if item_db.name ~= getCreatureName(cid) then
npcHandler:say('It\'s not offer of your item, say {set price} to view list of your items IDs.', cid)
npcHandler:resetNpc()
return true
end
if item_db.subType > 0 then
npcHandler:say('Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' (charges: ' .. item_db.subType .. ') in offer, price for each is ' .. item_db.price .. '. Do you want to change price? Say {no} or {price xxx}, where xxx is number of gp.', cid)
else
npcHandler:say('Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' in offer, price for each is ' .. item_db.price .. '. Do you want to change price? Say {no} or {price xxx}, where xxx is number of gp.', cid)
end
shop_last_item[cid] = {itemid = item_db.itemid, subType = item_db.subType}
else -- player ask for ID
local offer = getOfferOfPlayer(getCreatureName(cid))
if #offer == 0 then
npcHandler:say('You don\'t have any item in offer. You can\'t change price.', cid)
else
doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Your offers info:\n")
for i = 1, #offer do
if offer[i].subType > 0 then
doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, offer[i].count .. "x " .. offer[i].item_name .. " (charges: " .. offer[i].subType .. ") - price: " .. offer[i].price .. " - offer ID: " .. offer[i].id )
else
doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, offer[i].count .. "x " .. offer[i].item_name .. " - price: " .. offer[i].price .. " - offer ID: " .. offer[i].id )
end
end
npcHandler:say('To change price of item say {set price xx}. Where xx is ID of item.', cid)
end
npcHandler:resetNpc()
end
end
return true
end
function getCashBalanceFromItemsNPC(cid, message, keywords, parameters, node)
if(not npcHandler:isFocused(cid)) then
return false
end
npcHandler:say('I have ' .. getCash(getCreatureName(cid)) .. ' gp for you.', cid)
return true
end
function getCashFromItemsNPC(cid, message, keywords, parameters, node)
if(not npcHandler:isFocused(cid)) then
return false
end
local player_cash = getCash(getCreatureName(cid))
if player_cash > 0 then
if doPlayerAddMoney(cid, cost) ~= TRUE then
npcHandler:say('I can\'t give you cash. Try again.', cid)
else
npcHandler:say(player_cash ..' for you. It was a pleasure doing business with you.', cid)
end
else
npcHandler:say('I don\'t have cash for you.', cid)
end
return true
end
local sellitemprice1 = KeywordNode:new({'no'}, addItemToOfferNPC, {setprice = false})
local sellitemprice2 = KeywordNode:new({'price'}, addItemToOfferNPC, {setprice = true})
local sellitemprice3 = KeywordNode:new({'gp'}, addItemToOfferNPC, {setprice = true})
local setitemprice1 = KeywordNode:new({'no'}, setItemPriceNPC, {setprice = false})
local setitemprice2 = KeywordNode:new({'price'}, setItemPriceNPC, {setprice = true})
local setitemprice3 = KeywordNode:new({'gp'}, setItemPriceNPC, {setprice = true})
keywordHandler:addKeyword({'offer of'}, showOfferOfPlayerNPC, {})
keywordHandler:addKeyword({'search'}, showOfferOfItemNPC, {})
local node = keywordHandler:addKeyword({'add item'}, addItemToOfferNPC, {})
node:addChildKeywordNode(sellitemprice1)
node:addChildKeywordNode(sellitemprice2)
node:addChildKeywordNode(sellitemprice3)
local node = keywordHandler:addKeyword({'set price'}, setItemPriceNPC, {setprice = false})
node:addChildKeywordNode(setitemprice1)
node:addChildKeywordNode(setitemprice2)
node:addChildKeywordNode(setitemprice3)
local node = keywordHandler:addKeyword({'change price'}, setItemPriceNPC, {setprice = false})
node:addChildKeywordNode(setitemprice1)
node:addChildKeywordNode(setitemprice2)
node:addChildKeywordNode(setitemprice3)
keywordHandler:addKeyword({'my offer'}, showOfferOfPlayerNPC, {})
keywordHandler:addKeyword({'get item'}, showOfferOfPlayerNPC, {})
keywordHandler:addKeyword({'balance'}, getCashBalanceFromItemsNPC, {})
keywordHandler:addKeyword({'get cash'}, getCashFromItemsNPC, {})
keywordHandler:addKeyword({'withdraw'}, getCashFromItemsNPC, {})
local node = keywordHandler:addKeyword({'how to use'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'What you want to do? Say {add my item to offer}, {get my item from offer}, {check how much money from items I have}, {get my cash from items}, {change price of item in offer}, {buy item of other player} or {search item}.'})
node:addChildKeyword({'add my item to offer'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'First put your item in left hand (under BP slot), then say {add item xx} where xx is number of items that you want add to offer, then NPC will ask you for price, say {price yy}, where yy is price for 1 item.'})
node:addChildKeyword({'get my item from offer'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Say {my offer} or {get item} to view list of your items, all items will have price 1 gp, but when you press "Buy" you will get your item for free.'})
node:addChildKeyword({'check how mu'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Say {balance} to view how much money NPC has for you.'})
node:addChildKeyword({'get my cash'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Say {get cash} or {withdraw} to get your cash from NPC.'})
node:addChildKeyword({'change price of item in offer'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Say {change price} or {set price} to view list of your items, prices and offer IDs. Say {change price xx} or {set price xx}, where xx is item offer ID, then NPC will show you item name and ask for new price, say {price yy}, where yy is new price.'})
node:addChildKeyword({'buy item of other player'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Say {offer of Xx Yy}, where Xx Yy is name of player. NPC will show you offer of this player in trade window.'})
node:addChildKeyword({'search item'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Say {search Xxx Yyy}, where Xxx Yyy is name of item. Npc will show you few cheapest offers and names of players. That say {offer of Xxx}, where Xxx is name of player to view his offer and buy item.'})
npcHandler:setMessage(MESSAGE_GREET, "Greetings |PLAYERNAME|. I can trade your items with other players. Say {how to use} if you don\'t know commands.")
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
Code:
-- shop system
dofile("./config.lua")
function getOfferOfPlayer(name)
offer = {}
env = assert(luasql.mysql())
con = assert(env:connect(mysqlDatabase, mysqlUser, mysqlPass, mysqlHost, mysqlPort))
result_items = assert(con:execute("SELECT `id`, `name`, `item_name`, `itemid`, `subType`, `count`, `price` FROM `ots_playersshopsystem` WHERE `name` = '" .. escapeString(name) .. "' AND `count` > '0' AND `itemid` != '66'"))
item = result_items:fetch({}, "a")
while item do
table.insert(offer, {id = tonumber(item.id), name = tostring(item.name), item_name = tostring(item.item_name), itemid = tonumber(item.itemid), subType = tonumber(item.subType), count = tonumber(item.count), price = tonumber(item.price)})
item = result_items:fetch(item, "a")
end
con:close()
env:close()
return offer
end
function getOfferOfItem(item_name)
local offer = {}
env = assert(luasql.mysql())
con = assert(env:connect(mysqlDatabase, mysqlUser, mysqlPass, mysqlHost, mysqlPort))
result_items = assert(con:execute("SELECT `id`, `name`, `item_name`, `itemid`, `subType`, `count`, `price` FROM `ots_playersshopsystem` WHERE `item_name` = '" .. escapeString(item_name) .. "' AND `count` > '0' AND `itemid` != '66' ORDER BY `price` ASC LIMIT 5"))
item = result_items:fetch({}, "a")
while item do
table.insert(offer, {id = tonumber(item.id), name = tostring(item.name), item_name = tostring(item.item_name), itemid = tonumber(item.itemid), subType = tonumber(item.subType), count = tonumber(item.count), price = tonumber(item.price)})
item = result_items:fetch(item, "a")
end
con:close()
env:close()
return offer
end
function addItemToOffer(name, itemid, subType, count)
if itemid == 0 then
return false
end
env = assert(luasql.mysql())
con = assert(env:connect(mysqlDatabase, mysqlUser, mysqlPass, mysqlHost, mysqlPort))
local inDB_id = 0
local inDB_count = 0
local do_return = 0
local result_offers = assert(con:execute("SELECT `id`, `count` FROM `ots_playersshopsystem` WHERE `name` = '" .. escapeString(name) .. "' AND `itemid` = '" .. itemid .. "' AND `subType` = '" .. subType .. "' AND `itemid` != '66'"))
local offers = result_offers:fetch({}, "a")
while offers do
inDB_id = tonumber(offers.id)
inDB_count = tonumber(offers.count)
offers = result_offers:fetch (offers, "a")
end
if inDB_id ~= 0 then
assert(con:execute("UPDATE `ots_playersshopsystem` SET `count` = `ots_playersshopsystem`.`count` + " .. count .." WHERE `id` = '" .. inDB_id .. "' AND `subType` = '" .. subType .. "' AND `itemid` != '66'"))
else
assert(con:execute("INSERT INTO `tfs`.`ots_playersshopsystem` (`id`, `name`, `item_name`, `itemid`, `subType`, `count`, `price`) VALUES (NULL, '" .. escapeString(name) .. "', '" .. escapeString(getItemName(itemid)) .. "', '" .. itemid .. "', '" .. subType .. "', '" .. count .. "', 1000000)"))
end
con:close()
env:close()
return true
end
function removeItemsFromOffer(name, itemid, subType, count)
if count == 0 or itemid == 0 then
return false
end
env = assert(luasql.mysql())
con = assert(env:connect(mysqlDatabase, mysqlUser, mysqlPass, mysqlHost, mysqlPort))
assert(con:execute("UPDATE `ots_playersshopsystem` SET `count` = `ots_playersshopsystem`.`count` - " .. count .." WHERE `name` = '" .. escapeString(name) .. "' AND `itemid` = '" .. itemid .. "' AND `subType` = '" .. subType .. "' AND `itemid` != '66'"))
con:close()
env:close()
return true
end
function changePriceOfItem(name, itemid, subType, price)
if itemid == 0 or price == 0 then
return false
end
env = assert(luasql.mysql())
con = assert(env:connect(mysqlDatabase, mysqlUser, mysqlPass, mysqlHost, mysqlPort))
assert(con:execute("UPDATE `ots_playersshopsystem` SET `price` = " .. price .." WHERE `name` = '" .. escapeString(name) .. "' AND `itemid` = '" .. itemid .. "' AND `subType` = '" .. subType .. "' AND `itemid` != '66'"))
con:close()
env:close()
return true
end
function getItemWithId(id)
item2 = {id=0}
env = assert(luasql.mysql())
con = assert(env:connect(mysqlDatabase, mysqlUser, mysqlPass, mysqlHost, mysqlPort))
result_items = assert(con:execute("SELECT `id`, `name`, `item_name`, `itemid`, `subType`, `count`, `price` FROM `ots_playersshopsystem` WHERE `id` = '" .. id .. "' AND `count` > 0 AND `itemid` != '66'"))
item = result_items:fetch({}, "a")
while item do
item2 = {id = tonumber(item.id), name = tostring(item.name), item_name = tostring(item.item_name), itemid = tonumber(item.itemid), subType = tonumber(item.subType), count = tonumber(item.count), price = tonumber(item.price)}
item = result_items:fetch(item, "a")
end
con:close()
env:close()
return item2
end
function getItemWithItemId(name, itemid, subType)
if itemid == 0 then
return false
end
item2 = {id=0}
env = assert(luasql.mysql())
con = assert(env:connect(mysqlDatabase, mysqlUser, mysqlPass, mysqlHost, mysqlPort))
result_items = assert(con:execute("SELECT `id`, `name`, `item_name`, `itemid`, `subType`, `count`, `price` FROM `ots_playersshopsystem` WHERE `name` = '" .. escapeString(name) .. "' AND `itemid` = '" .. itemid .. "' AND `subType` = '" .. subType .. "' AND `count` > 0 AND `itemid` != '66'"))
item = result_items:fetch({}, "a")
while item do
item2 = {id = tonumber(item.id), name = tostring(item.name), item_name = tostring(item.item_name), itemid = tonumber(item.itemid), subType = tonumber(item.subType), count = tonumber(item.count), price = tonumber(item.price)}
item = result_items:fetch(item, "a")
end
con:close()
env:close()
return item2
end
function getCash(name)
env = assert(luasql.mysql())
con = assert(env:connect(mysqlDatabase, mysqlUser, mysqlPass, mysqlHost, mysqlPort))
local inDB_id = 0
local inDB_count = 0
local do_return = 0
local result_offers = assert(con:execute("SELECT `id`, `count` FROM `ots_playersshopsystem` WHERE `name` = '" .. escapeString(name) .. "' AND `itemid` = '66'"))
local offers = result_offers:fetch({}, "a")
while offers do
inDB_id = tonumber(offers.id)
inDB_count = tonumber(offers.count)
offers = result_offers:fetch (offers, "a")
end
if inDB_id == 0 then
assert(con:execute("INSERT INTO `tfs`.`ots_playersshopsystem` (`id`, `name`, `item_name`, `itemid`, `count`, `price`) VALUES ('', '" .. escapeString(name) .. "', 'Player Cash', '66', '0', '0')"))
end
con:close()
env:close()
return inDB_count
end
function setCash(name, count)
env = assert(luasql.mysql())
con = assert(env:connect(mysqlDatabase, mysqlUser, mysqlPass, mysqlHost, mysqlPort))
assert(con:execute("UPDATE `ots_playersshopsystem` SET `count` = " .. count ..", `price` = " .. count .." WHERE `name` = '" .. escapeString(name) .. "' AND `itemid` = '66'"))
con:close()
env:close()
return true
end
function addPlayerItemFromShop(cid, itemid, amount, subType)
local amount = amount or 1
local subType = subType or 0
if(isItemStackable(itemid) == TRUE) then
local item = doCreateItemEx(itemid, amount)
local ret = doPlayerAddItemEx(cid, item)
if(ret ~= RETURNVALUE_NOERROR) then
return {}, 0
end
return {item}, amount
end
local items = {}
local ret = 0
local a = 0
for i = 1, amount do
items[i] = doCreateItemEx(itemid, subType)
ret = doPlayerAddItemEx(cid, items[i])
if(ret ~= RETURNVALUE_NOERROR) then
break
end
a = a + 1
end
return items, a
end
TFS83.exe
If you use your modified version of TFS 0.2 pl 16 engine, you must only replace your function (file npc.cpp):
PHP:
int32_t NpcScriptInterface::luaOpenShopWindow(lua_State* L)
{
...
}
PHP:
int32_t NpcScriptInterface::luaOpenShopWindow(lua_State* L)
{
//openShopWindow(cid, items, onBuy callback, onSell callback)
ScriptEnviroment* env = getScriptEnv();
Npc* npc = env->getNpc();
if(!npc)
{
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
lua_pushnumber(L, LUA_ERROR);
return 1;
}
int32_t sellCallback = -1;
if(lua_isfunction(L, -1) == 0)
lua_pop(L, 1); // skip it - use default value
else
sellCallback = popCallback(L);
int32_t buyCallback = -1;
if(lua_isfunction(L, -1) == 0)
lua_pop(L, 1);
else
buyCallback = popCallback(L);
if(lua_istable(L, -1) == 0)
{
reportError(__FUNCTION__, "item list is not a table.");
lua_pushnumber(L, LUA_ERROR);
return 1;
}
ShopInfo item;
npc->shopItemList.clear();
// first key
lua_pushnil(L);
while(lua_next(L, -2) != 0)
{
item.itemId = getField(L, "id");
item.subType = getField(L, "subType");
item.buyPrice = getField(L, "buy");
item.sellPrice = getField(L, "sell");
item.itemName = getFieldString(L, "name");
npc->shopItemList.push_back(item);
lua_pop(L, 1);
}
sortItems(npc->shopItemList);
lua_pop(L, 1);
Player* player = env->getPlayerByUID(popNumber(L));
if(!player)
{
reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
lua_pushnumber(L, LUA_ERROR);
return 1;
}
player->closeShopWindow();
npc->addShopPlayer(player);
player->setShopOwner(npc, buyCallback, sellCallback);
player->sendShop(npc->shopItemList);
player->sendGoods(g_game.getMoney(player), player->parseGoods(npc->shopItemList));
lua_pushnumber(L, LUA_NO_ERROR);
return 1;
}
Last edited by a moderator: