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

Elexonic

Well-Known Member
Joined
Jun 18, 2008
Messages
1,920
Reaction score
59
Last Page
anyone know which one I put script is better?


What script is beter?

Code:
function customCallbackOnBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks, shopWindow)
		local shopItem, npcHandler = nil, NpcHandler
		for _, item in ipairs(shopWindow) do
			if(item.id == itemid) then
				if item.subType then
					if(item.subType == subType) then
						shopItem = item
						break
					end
				else
					shopItem = item
					break
				end
			end
		end
 
		if(shopItem == nil) then
			error("[ShopModule.onBuy]", "Item not found on shopItems list")
			return false
		end
 
		if(shopItem.buy == -1) then
			error("[ShopModule.onSell]", "Attempt to purchase an item which is only sellable")
			return false
		end
 
		local backpack, totalCost = 1988, amount * shopItem.buy
		if(inBackpacks) then
			totalCost = isItemStackable(itemid) == TRUE and totalCost + 20 or totalCost + (math.max(1, math.floor(amount / getContainerCapById(backpack))) * 20)
		end
 
		if(getPlayerMoney(cid) < totalCost) then
			doPlayerSendCancel(cid, npcHandler:parseMessage(npcHandler:getMessage(MESSAGE_NEEDMONEY), {[TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = amount, [TAG_TOTALCOST] = totalCost, [TAG_ITEMNAME] = shopItem.name}))
			return false
		end
 
		local subType = shopItem.subType or 1
		local a, b = doNpcSellItem(cid, itemid, amount, subType, ignoreCap, inBackpacks, backpack)
		if(a < amount) then
			local msgId = MESSAGE_NEEDMORESPACE
			if(a == 0) then
				msgId = MESSAGE_NEEDSPACE
			end
 
			doPlayerSendCancel(cid, npcHandler:parseMessage(npcHandler:getMessage(msgId), {[TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = amount, [TAG_TOTALCOST] = totalCost, [TAG_ITEMNAME] = shopItem.name, [TAG_ITEMCOUNT] = a}))
 
			if(a > 0) then
				doPlayerRemoveMoney(cid, ((a * shopItem.buy) + (b * 20)))
				return true
			end
 
			return false
		end
		doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, npcHandler:parseMessage(npcHandler:getMessage(MESSAGE_BOUGHT), {[TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = amount, [TAG_TOTALCOST] = totalCost, [TAG_ITEMNAME] = shopItem.name}))
		doPlayerRemoveMoney(cid, totalCost)
 
		return true
	end
 
	function customCallbackOnSell(cid, itemid, subType, amount, ignoreCap, inBackpacks)
		local shopItem, npcHandler = nil, NpcHandler
		for _, item in ipairs(self.npcHandler.shopItems) do
			if(item.id == itemid and item.subType == subType) then
				shopItem = item
				break
			end
		end
 
		if(shopItem == nil) then
			error("[ShopModule.onBuy]", "Item not found on shopItems list")
			return false
		end
 
		if(shopItem.sell == -1) then
			error("[ShopModule.onSell]", "Attempt to sell an item which is only buyable")
			return false
		end
 
		local parseInfo = {
			[TAG_PLAYERNAME] = getPlayerName(cid),
			[TAG_ITEMCOUNT] = amount,
			[TAG_TOTALCOST] = amount * shopItem.sell,
			[TAG_ITEMNAME] = shopItem.name
		}
 
		if(subType < 1) then
			subType = -1
		end
 
		if(doPlayerRemoveItem(cid, itemid, amount, subType) == TRUE) then
			doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, self.npcHandler:parseMessage(self.npcHandler:getMessage(MESSAGE_SOLD), parseInfo))
			doPlayerAddMoney(cid, amount * shopItem.sell)
			if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
				self.npcHandler.talkStart[cid] = os.time()
			else
				self.npcHandler.talkStart = os.time()
			end
 
			return true
		end
		doPlayerSendCancel(cid, self.npcHandler:parseMessage(self.npcHandler:getMessage(MESSAGE_NEEDITEM), parseInfo))
		if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
			self.npcHandler.talkStart[cid] = os.time()
		else
			self.npcHandler.talkStart = os.time()
		end
 
		return false
	end


Or

Code:
function customCallbackOnBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks, shopWindow)
	local shopItem, npcHandler = nil, NpcHandler
	for _, item in ipairs(shopWindow) do
		if not item.subType then
			item.subType = (isItemFluidContainer(item.id) == TRUE or isItemStackable(item.id) == TRUE) and 0 or 1
		end
		if(item.id == itemid and (item.subType == subType)) then
			shopItem = item
			break
		end
	end
 
	if(shopItem == nil) then
		error("[ShopModule.onBuy]", "Item not found on shopItems list")
		return false
	end
 
	if(shopItem.buy < 0) then
		error("[ShopModule.onSell]", "Attempt to purchase an item which is only sellable")
		return false
	end
 
	local backpack, totalCost = 1988, amount * shopItem.buy
	if(inBackpacks) then
		totalCost = isItemStackable(itemid) == TRUE and totalCost + 20 or totalCost + (math.max(1, math.floor(amount / getContainerCapById(backpack))) * 20)
	end
 
	if(getPlayerMoney(cid) < totalCost) then
		doPlayerSendCancel(cid, npcHandler:parseMessage(npcHandler:getMessage(MESSAGE_NEEDMONEY), {[TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = amount, [TAG_TOTALCOST] = totalCost, [TAG_ITEMNAME] = shopItem.name}))
		return false
	end
 
	local subType = shopItem.subType or isItemFluidContainer(itemid) == TRUE and 0 or 1
	local a, b = doNpcSellItem(cid, itemid, amount, subType, ignoreCap, inBackpacks, backpack)
	if(a < amount) then
		local msgId = MESSAGE_NEEDMORESPACE
		if(a == 0) then
			msgId = MESSAGE_NEEDSPACE
		end
 
		doPlayerSendCancel(cid, npcHandler:parseMessage(npcHandler:getMessage(msgId), {[TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = amount, [TAG_TOTALCOST] = totalCost, [TAG_ITEMNAME] = shopItem.name, [TAG_ITEMCOUNT] = a}))
 
		if(a > 0) then
			doPlayerRemoveMoney(cid, ((a * shopItem.buy) + (b * 20)))
			return true
		end
 
		return false
	end
	doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, npcHandler:parseMessage(npcHandler:getMessage(MESSAGE_BOUGHT), {[TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = amount, [TAG_TOTALCOST] = totalCost, [TAG_ITEMNAME] = shopItem.name}))
	doPlayerRemoveMoney(cid, totalCost)
 
	return true
end
 
function customCallbackOnSell(cid, itemid, subType, amount, ignoreCap, inBackpacks, shopWindow)
	local shopItem, npcHandler, subType = nil, NpcHandler, subType or 0
	for _, item in ipairs(shopWindow) do
		item.subType = not item.subType and 0 or item.subType
		if(item.id == itemid and (isItemFluidContainer(itemid) == FALSE or isItemFluidContainer(itemid) == TRUE and item.subType == subType)) then
			shopItem = item
			break
		end
	end
 
	if(shopItem == nil) then
		error("[ShopModule.onBuy]", "Item not found on shopItems list")
		return false
	end
 
	if(shopItem.sell < 0) then
		error("[ShopModule.onSell]", "Attempt to sell an item which is only buyable")
		return false
	end
 
	if(doPlayerRemoveItem(cid, itemid, amount, isItemFluidContainer(itemid) == TRUE and subType or isItemStackable(itemid) == TRUE and amount or 1) == TRUE) then
		doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, npcHandler:parseMessage(npcHandler:getMessage(MESSAGE_SOLD), {[TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = amount, [TAG_TOTALCOST] = amount * shopItem.sell, [TAG_ITEMNAME] = shopItem.name}))
		doPlayerAddMoney(cid, amount * shopItem.sell)
 
		return true
	end
	doPlayerSendCancel(cid, npcHandler:parseMessage(npcHandler:getMessage(MESSAGE_NEEDITEM), {[TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = amount, [TAG_TOTALCOST] = amount * shopItem.sell, [TAG_ITEMNAME] = shopItem.name}))
 
	return false
end
 
Last edited:
This is because function creatureSayCallback is a non-existent function.
Keep in mind, there are multiple functions that 0.3 has that 0.2 does not have.
I haven't tried, but you could just take the function from 0.3 and add it into 0.2.
Try adding these functions into global.lua:

or.. use 0.4?
change your folder
npc/lib

or try this NPC.
Lua:
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)
	local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid
	if (msgcontains(msg, "hello") or msgcontains(msg, "hi")) and (not npcHandler:isFocused(cid)) then
		npcHandler:say("Hello, ".. getCreatureName(cid) .." and welcome to my little forge.", cid, TRUE)
		npcHandler:addFocus(cid)
	elseif(not npcHandler:isFocused(cid)) then
		return false
	elseif msgcontains(msg, "bye") or msgcontains(msg, "farewell") then
		npcHandler:say("Bye.", cid, TRUE)
		npcHandler:releaseFocus(cid)
	elseif msgcontains(msg, "trade") then
		local items = {
			{name="axe", id=2386, buy=20, sell=7},
			{name="battle hammer", id=2417, buy=350},
			{name="brass armor", id=2465, buy=450, sell=150},
			{name="chain armor", id=2464, buy=200, sell=70},
			{name="chain helmet", id=2458, buy=52, sell=17},
			{name="chain legs", id=2648, buy=80, sell=25},
			{name="dagger", id=2351, buy=5},
			{name="hand axe", id=2380, buy=8, sell=4},
			{name="leather armor", id=2467, buy=35, sell=12},
			{name="leather helmet", id=2461, buy=12},
			{name="mace", id=2398, buy=90, sell=30},
			{name="rapier", id=2384, buy=15, sell=5},
			{name="sabre", id=2385, buy=35, sell=12},
			{name="spear", id=2389, buy=10, sell=3},
			{name="steel shield", id=2509, buy=240, sell=80},
			{name="sword", id=2376, buy=85, sell=25},
			{name="throwing knife", id=2410, buy=25},
			{name="wooden shield", id=2512, buy=15, sell=3},
			{name="battle axe", id=2378, sell=80},
			{name="battle shield", id=2513, sell=95},
			{name="halberd", id=2381, sell=400},
			{name="morning star", id=2394, sell=90},
			{name="plate armor", id=2463, sell=400},
			{name="steel helmet", id=2457, sell=190},
			{name="two handed sword", id=2377, sell=450},
			{name="warmaster's wristguards", id=11316, sell=200}
		}
		if getPlayerStorageValue(cid, 85300) >= 3 then
			table.insert(items, {name="lizard weapon rack kit", id=11120, buy=500})
		end
		if getPlayerStorageValue(cid, 85300) >= 9 then
			table.insert(items, {name="twin hooks", id=11303, buy=1100, sell=500})
			table.insert(items, {name="zaoan halberd", id=11317, buy=1200, sell=500})
			table.insert(items, {name="bone shoulderplate", id=11315, sell=150})
			table.insert(items, {name="broken halberd", id=11329, sell=100})
			table.insert(items, {name="cursed shoulder spikes", id=11321, sell=320})
			table.insert(items, {name="drachaku", id=11302, sell=10000})
			table.insert(items, {name="drakinata", id=11299, sell=10000})
			table.insert(items, {name="draken boots", id=12621, sell=40000})
			table.insert(items, {name="guardian boots", id=11234, sell=35000})
			table.insert(items, {name="high guard's shoulderplates", id=11327, sell=130})
			table.insert(items, {name="legionnaire flags", id=11328, sell=500})
			table.insert(items, {name="sais", id=11300, sell=16500})
			table.insert(items, {name="spiked iron ball", id=11319, sell=100})
			table.insert(items, {name="trashed draken boots", id=12607, sell=40000})
			table.insert(items, {name="twiceslicer", id=12574, sell=28000})
			table.insert(items, {name="wailing widow's necklace", id=11323, sell=3000})
			table.insert(items, {name="zaoan armor", id=11295, sell=14000})
			table.insert(items, {name="zaoan helmet", id=11296, sell=45000})
			table.insert(items, {name="zaoan legs", id=11298, sell=14000})
			table.insert(items, {name="zaoan shoes", id=11297, sell=5000})
			table.insert(items, {name="zaoan sword", id=11301, sell=30000})
			table.insert(items, {name="zaogun's shoulderplates", id=11325, sell=150})
		end
		openShopWindow(cid, items,
			function(cid, itemid, subType, amount, ignoreCap, inBackpacks)
				customCallbackOnBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks, items)
			end,
			function(cid, itemid, subType, amount, ignoreCap, inBackpacks)
				customCallbackOnSell(cid, itemid, subType, amount, ignoreCap, inBackpacks, items)
			end
		)
		npcHandler:say("Of course, just browse through my wares.", cid)
	end
	return TRUE
end

npcHandler:setMessage(MESSAGE_WALKAWAY, "Bye.")
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)

Just have error in console? copy and paste here.
 
What script is beter?

Code:
function customCallbackOnBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks, shopWindow)
		local shopItem, npcHandler = nil, NpcHandler
		for _, item in ipairs(shopWindow) do
			if(item.id == itemid) then
				if item.subType then
					if(item.subType == subType) then
						shopItem = item
						break
					end
				else
					shopItem = item
					break
				end
			end
		end
 
		if(shopItem == nil) then
			error("[ShopModule.onBuy]", "Item not found on shopItems list")
			return false
		end
 
		if(shopItem.buy == -1) then
			error("[ShopModule.onSell]", "Attempt to purchase an item which is only sellable")
			return false
		end
 
		local backpack, totalCost = 1988, amount * shopItem.buy
		if(inBackpacks) then
			totalCost = isItemStackable(itemid) == TRUE and totalCost + 20 or totalCost + (math.max(1, math.floor(amount / getContainerCapById(backpack))) * 20)
		end
 
		if(getPlayerMoney(cid) < totalCost) then
			doPlayerSendCancel(cid, npcHandler:parseMessage(npcHandler:getMessage(MESSAGE_NEEDMONEY), {[TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = amount, [TAG_TOTALCOST] = totalCost, [TAG_ITEMNAME] = shopItem.name}))
			return false
		end
 
		local subType = shopItem.subType or 1
		local a, b = doNpcSellItem(cid, itemid, amount, subType, ignoreCap, inBackpacks, backpack)
		if(a < amount) then
			local msgId = MESSAGE_NEEDMORESPACE
			if(a == 0) then
				msgId = MESSAGE_NEEDSPACE
			end
 
			doPlayerSendCancel(cid, npcHandler:parseMessage(npcHandler:getMessage(msgId), {[TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = amount, [TAG_TOTALCOST] = totalCost, [TAG_ITEMNAME] = shopItem.name, [TAG_ITEMCOUNT] = a}))
 
			if(a > 0) then
				doPlayerRemoveMoney(cid, ((a * shopItem.buy) + (b * 20)))
				return true
			end
 
			return false
		end
		doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, npcHandler:parseMessage(npcHandler:getMessage(MESSAGE_BOUGHT), {[TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = amount, [TAG_TOTALCOST] = totalCost, [TAG_ITEMNAME] = shopItem.name}))
		doPlayerRemoveMoney(cid, totalCost)
 
		return true
	end
 
	function customCallbackOnSell(cid, itemid, subType, amount, ignoreCap, inBackpacks)
		local shopItem, npcHandler = nil, NpcHandler
		for _, item in ipairs(self.npcHandler.shopItems) do
			if(item.id == itemid and item.subType == subType) then
				shopItem = item
				break
			end
		end
 
		if(shopItem == nil) then
			error("[ShopModule.onBuy]", "Item not found on shopItems list")
			return false
		end
 
		if(shopItem.sell == -1) then
			error("[ShopModule.onSell]", "Attempt to sell an item which is only buyable")
			return false
		end
 
		local parseInfo = {
			[TAG_PLAYERNAME] = getPlayerName(cid),
			[TAG_ITEMCOUNT] = amount,
			[TAG_TOTALCOST] = amount * shopItem.sell,
			[TAG_ITEMNAME] = shopItem.name
		}
 
		if(subType < 1) then
			subType = -1
		end
 
		if(doPlayerRemoveItem(cid, itemid, amount, subType) == TRUE) then
			doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, self.npcHandler:parseMessage(self.npcHandler:getMessage(MESSAGE_SOLD), parseInfo))
			doPlayerAddMoney(cid, amount * shopItem.sell)
			if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
				self.npcHandler.talkStart[cid] = os.time()
			else
				self.npcHandler.talkStart = os.time()
			end
 
			return true
		end
		doPlayerSendCancel(cid, self.npcHandler:parseMessage(self.npcHandler:getMessage(MESSAGE_NEEDITEM), parseInfo))
		if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
			self.npcHandler.talkStart[cid] = os.time()
		else
			self.npcHandler.talkStart = os.time()
		end
 
		return false
	end


Or

Code:
function customCallbackOnBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks, shopWindow)
	local shopItem, npcHandler = nil, NpcHandler
	for _, item in ipairs(shopWindow) do
		if not item.subType then
			item.subType = (isItemFluidContainer(item.id) == TRUE or isItemStackable(item.id) == TRUE) and 0 or 1
		end
		if(item.id == itemid and (item.subType == subType)) then
			shopItem = item
			break
		end
	end
 
	if(shopItem == nil) then
		error("[ShopModule.onBuy]", "Item not found on shopItems list")
		return false
	end
 
	if(shopItem.buy < 0) then
		error("[ShopModule.onSell]", "Attempt to purchase an item which is only sellable")
		return false
	end
 
	local backpack, totalCost = 1988, amount * shopItem.buy
	if(inBackpacks) then
		totalCost = isItemStackable(itemid) == TRUE and totalCost + 20 or totalCost + (math.max(1, math.floor(amount / getContainerCapById(backpack))) * 20)
	end
 
	if(getPlayerMoney(cid) < totalCost) then
		doPlayerSendCancel(cid, npcHandler:parseMessage(npcHandler:getMessage(MESSAGE_NEEDMONEY), {[TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = amount, [TAG_TOTALCOST] = totalCost, [TAG_ITEMNAME] = shopItem.name}))
		return false
	end
 
	local subType = shopItem.subType or isItemFluidContainer(itemid) == TRUE and 0 or 1
	local a, b = doNpcSellItem(cid, itemid, amount, subType, ignoreCap, inBackpacks, backpack)
	if(a < amount) then
		local msgId = MESSAGE_NEEDMORESPACE
		if(a == 0) then
			msgId = MESSAGE_NEEDSPACE
		end
 
		doPlayerSendCancel(cid, npcHandler:parseMessage(npcHandler:getMessage(msgId), {[TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = amount, [TAG_TOTALCOST] = totalCost, [TAG_ITEMNAME] = shopItem.name, [TAG_ITEMCOUNT] = a}))
 
		if(a > 0) then
			doPlayerRemoveMoney(cid, ((a * shopItem.buy) + (b * 20)))
			return true
		end
 
		return false
	end
	doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, npcHandler:parseMessage(npcHandler:getMessage(MESSAGE_BOUGHT), {[TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = amount, [TAG_TOTALCOST] = totalCost, [TAG_ITEMNAME] = shopItem.name}))
	doPlayerRemoveMoney(cid, totalCost)
 
	return true
end
 
function customCallbackOnSell(cid, itemid, subType, amount, ignoreCap, inBackpacks, shopWindow)
	local shopItem, npcHandler, subType = nil, NpcHandler, subType or 0
	for _, item in ipairs(shopWindow) do
		item.subType = not item.subType and 0 or item.subType
		if(item.id == itemid and (isItemFluidContainer(itemid) == FALSE or isItemFluidContainer(itemid) == TRUE and item.subType == subType)) then
			shopItem = item
			break
		end
	end
 
	if(shopItem == nil) then
		error("[ShopModule.onBuy]", "Item not found on shopItems list")
		return false
	end
 
	if(shopItem.sell < 0) then
		error("[ShopModule.onSell]", "Attempt to sell an item which is only buyable")
		return false
	end
 
	if(doPlayerRemoveItem(cid, itemid, amount, isItemFluidContainer(itemid) == TRUE and subType or isItemStackable(itemid) == TRUE and amount or 1) == TRUE) then
		doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, npcHandler:parseMessage(npcHandler:getMessage(MESSAGE_SOLD), {[TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = amount, [TAG_TOTALCOST] = amount * shopItem.sell, [TAG_ITEMNAME] = shopItem.name}))
		doPlayerAddMoney(cid, amount * shopItem.sell)
 
		return true
	end
	doPlayerSendCancel(cid, npcHandler:parseMessage(npcHandler:getMessage(MESSAGE_NEEDITEM), {[TAG_PLAYERNAME] = getPlayerName(cid), [TAG_ITEMCOUNT] = amount, [TAG_TOTALCOST] = amount * shopItem.sell, [TAG_ITEMNAME] = shopItem.name}))
 
	return false
end
 
Back
Top