Ir para conteúdo
  • Cadastre-se

Posts Recomendados

Galera meu ot quando um payer vai compra em qualquer npc atravez do trade acontece o seguint erro

[10:59:35.721] [Error - NpcScript Interface]

[10:59:35.721] (Unknown script file)

[10:59:35.721] Description:

[10:59:35.721] data/npc/lib/npcsystem/npchandler.lua:263: bad argument #1 to 'unpack' (table expected, got nil)

[10:59:35.721] stack traceback:

[10:59:35.721] [C]: in function 'unpack'

[10:59:35.721] data/npc/lib/npcsystem/npchandler.lua:263: in function 'processModuleCallback'

[10:59:35.721] data/npc/lib/npcsystem/npchandler.lua:440: in function 'onBuy'

[10:59:35.721] data/npc/lib/npcsystem/modules.lua:1278: in function <data/npc/lib/npcsystem/modules.lua:1278>

IMAGE DO ERRO \/

E os player nao recebem os itens..bugtb.png

lib.rar

Editado por Fabiano Alberto (veja o histórico de edições)

SE AJUDEI REP+ ;D, NÃO CUSTA NADA.

uRti.png

<a href="http://central.evenhost.net/aff.php?aff=020"><img src="http://i.imm.io/uRti.png" width="500" height="82" border="0"></a>

Link para o post
Compartilhar em outros sites

Não é o mesmo erro.

Edit: fiz o que pede o topico e continua mesma coisa

Editado por Fabiano Alberto (veja o histórico de edições)

SE AJUDEI REP+ ;D, NÃO CUSTA NADA.

uRti.png

<a href="http://central.evenhost.net/aff.php?aff=020"><img src="http://i.imm.io/uRti.png" width="500" height="82" border="0"></a>

Link para o post
Compartilhar em outros sites

Poderia postar o script do npc e a pasta lib dos npcs?

Editado por comedinhasss (veja o histórico de edições)

Bruno de Carvalho Câmara / Administrador TibiaKing

[email protected]


 

btn_donateCC_LG.gif

 

Em 26/12/2016 em 03:47, Spraypaint disse:

A força da alienação vem dessa fragilidade dos indivíduos, quando apenas conseguem identificar o que os separa e não o que os une.

-miltinho

 

wMwSJFE.png?1

 

Link para o post
Compartilhar em outros sites

npchandler

-- Advanced NPC System (Created by Jiddo),

-- Modified by Talaturen.

if(NpcHandler == nil) then

-- Constant talkdelay behaviors.

TALKDELAY_NONE = 0 -- No talkdelay. Npc will reply immedeatly.

TALKDELAY_ONTHINK = 1 -- Talkdelay handled through the onThink callback function. (Default)

TALKDELAY_EVENT = 2 -- Not yet implemented

-- Currently applied talkdelay behavior. TALKDELAY_ONTHINK is default.

NPCHANDLER_TALKDELAY = TALKDELAY_ONTHINK

-- Constant conversation behaviors.

CONVERSATION_DEFAULT = 0 -- Conversation through default window, like it was before 8.2 update.

CONVERSATION_PRIVATE = 1 -- Conversation through NPCs chat window, as of 8.2 update. (Default)

--Small Note: Private conversations also means the NPC will use multi-focus system.

-- Currently applied conversation behavior. CONVERSATION_PRIVATE is default.

NPCHANDLER_CONVBEHAVIOR = CONVERSATION_PRIVATE

-- Constant indexes for defining default messages.

MESSAGE_GREET = 1 -- When the player greets the npc.

MESSAGE_FAREWELL = 2 -- When the player unGreets the npc.

MESSAGE_BUY = 3 -- When the npc asks the player if he wants to buy something.

MESSAGE_ONBUY = 4 -- When the player successfully buys something via talk.

MESSAGE_BOUGHT = 5 -- When the player bought something through the shop window.

MESSAGE_SELL = 6 -- When the npc asks the player if he wants to sell something.

MESSAGE_ONSELL = 7 -- When the player successfully sells something via talk.

MESSAGE_SOLD = 8 -- When the player sold something through the shop window.

MESSAGE_MISSINGMONEY = 9 -- When the player does not have enough money.

MESSAGE_NEEDMONEY = 10 -- Same as above, used for shop window.

MESSAGE_MISSINGITEM = 11 -- When the player is trying to sell an item he does not have.

MESSAGE_NEEDITEM = 12 -- Same as above, used for shop window.

MESSAGE_NEEDSPACE = 13 -- When the player don't have any space to buy an item

MESSAGE_NEEDMORESPACE = 14 -- When the player has some space to buy an item, but not enough space

MESSAGE_IDLETIMEOUT = 15 -- When the player has been idle for longer then idleTime allows.

MESSAGE_WALKAWAY = 16 -- When the player walks out of the talkRadius of the npc.

MESSAGE_DECLINE = 17 -- When the player says no to something.

MESSAGE_SENDTRADE = 18 -- When the npc sends the trade window to the player

MESSAGE_NOSHOP = 19 -- When the npc's shop is requested but he doesn't have any

MESSAGE_ONCLOSESHOP = 20 -- When the player closes the npc's shop window

MESSAGE_ALREADYFOCUSED = 21 -- When the player already has the focus of this npc.

MESSAGE_PLACEDINQUEUE = 22 -- When the player has been placed in the costumer queue.

-- Constant indexes for callback functions. These are also used for module callback ids.

CALLBACK_CREATURE_APPEAR = 1

CALLBACK_CREATURE_DISAPPEAR = 2

CALLBACK_CREATURE_SAY = 3

CALLBACK_ONTHINK = 4

CALLBACK_GREET = 5

CALLBACK_FAREWELL = 6

CALLBACK_MESSAGE_DEFAULT = 7

CALLBACK_PLAYER_ENDTRADE = 8

CALLBACK_PLAYER_CLOSECHANNEL = 9

CALLBACK_ONBUY = 10

CALLBACK_ONSELL = 11

-- Addidional module callback ids

CALLBACK_MODULE_INIT = 12

CALLBACK_MODULE_RESET = 13

-- Constant strings defining the keywords to replace in the default messages.

TAG_PLAYERNAME = '|PLAYERNAME|'

TAG_ITEMCOUNT = '|ITEMCOUNT|'

TAG_TOTALCOST = '|TOTALCOST|'

TAG_ITEMNAME = '|ITEMNAME|'

TAG_QUEUESIZE = '|QUEUESIZE|'

NpcHandler = {

keywordHandler = nil,

focuses = nil,

talkStart = nil,

idleTime = 90,

talkRadius = 4,

talkDelayTime = 1, -- Seconds to delay outgoing messages.

queue = nil,

talkDelay = nil,

callbackFunctions = nil,

modules = nil,

shopItems = nil, -- They must be here since ShopModule uses "static" functions

messages = {

-- These are the default replies of all npcs. They can/should be changed individually for each npc.

[MESSAGE_GREET] = 'Welcome, |PLAYERNAME|! I have been expecting you.',

[MESSAGE_FAREWELL] = 'Good bye, |PLAYERNAME|!',

[MESSAGE_BUY] = 'Do you want to buy |ITEMCOUNT| |ITEMNAME| for |TOTALCOST| gold coins?',

[MESSAGE_ONBUY] = 'It was a pleasure doing business with you.',

[MESSAGE_BOUGHT] = 'Bought |ITEMCOUNT|x |ITEMNAME| for |TOTALCOST| gold.',

[MESSAGE_SELL] = 'Do you want to sell |ITEMCOUNT| |ITEMNAME| for |TOTALCOST| gold coins?',

[MESSAGE_ONSELL] = 'Thank you for this |ITEMNAME|, |PLAYERNAME| gold.',

[MESSAGE_SOLD] = 'Sold |ITEMCOUNT|x |ITEMNAME| for |TOTALCOST| gold.',

[MESSAGE_MISSINGMONEY] = 'Sorry, you don\'t have enough money.',

[MESSAGE_NEEDMONEY] = 'You do not have enough money.',

[MESSAGE_MISSINGITEM] = 'You don\'t even have that item, |PLAYERNAME|!',

[MESSAGE_NEEDITEM] = 'You do not have this object.',

[MESSAGE_NEEDSPACE] = 'You do not have enough capacity.',

[MESSAGE_NEEDMORESPACE] = 'You do not have enough capacity for all items.',

[MESSAGE_IDLETIMEOUT] = 'Next, please!',

[MESSAGE_WALKAWAY] = 'How rude!',

[MESSAGE_DECLINE] = 'Not good enough, is it... ?',

[MESSAGE_SENDTRADE] = 'Here\'s my offer, |PLAYERNAME|. Don\'t you like it?',

[MESSAGE_NOSHOP] = 'Sorry, I\'m not offering anything.',

[MESSAGE_ONCLOSESHOP] = 'Thank you, come back when you want something more.',

[MESSAGE_ALREADYFOCUSED]= '|PLAYERNAME|! I am already talking to you...',

[MESSAGE_PLACEDINQUEUE] = '|PLAYERNAME|, please wait for your turn. There are |QUEUESIZE| customers before you.'

}

}

-- Creates a new NpcHandler with an empty callbackFunction stack.

function NpcHandler:new(keywordHandler)

local obj = {}

obj.callbackFunctions = {}

obj.modules = {}

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

obj.focuses = {}

obj.talkStart = {}

else

obj.queue = Queue:new(obj)

obj.focuses = 0

obj.talkStart = 0

end

obj.talkDelay = {}

obj.keywordHandler = keywordHandler

obj.messages = {}

obj.shopItems = {}

setmetatable(obj.messages, self.messages)

self.messages.__index = self.messages

setmetatable(obj, self)

self.__index = self

return obj

end

-- Re-defines the maximum idle time allowed for a player when talking to this npc.

function NpcHandler:setMaxIdleTime(newTime)

self.idleTime = newTime

end

-- Attackes a new keyword handler to this npchandler

function NpcHandler:setKeywordHandler(newHandler)

self.keywordHandler = newHandler

end

-- Function used to change the focus of this npc.

function NpcHandler:addFocus(newFocus)

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

if(self:isFocused(newFocus)) then

return

end

table.insert(self.focuses, newFocus)

else

self.focuses = newFocus

end

self:updateFocus()

end

NpcHandler.changeFocus = NpcHandler.addFocus --"changeFocus" looks better for CONVERSATION_DEFAULT

-- Function used to verify if npc is focused to certain player

function NpcHandler:isFocused(focus)

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

for k,v in pairs(self.focuses) do

if v == focus then

return true

end

end

return false

end

return (self.focuses == focus)

end

-- This function should be called on each onThink and makes sure the npc faces the player it is talking to.

-- Should also be called whenever a new player is focused.

function NpcHandler:updateFocus()

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

for pos, focus in pairs(self.focuses) do

if(focus ~= nil) then

doNpcSetCreatureFocus(focus)

return

end

end

doNpcSetCreatureFocus(0)

else

doNpcSetCreatureFocus(self.focuses)

end

end

-- Used when the npc should un-focus the player.

function NpcHandler:releaseFocus(focus)

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

if(not self:isFocused(focus)) then

return

end

local pos = nil

for k,v in pairs(self.focuses) do

if v == focus then

pos = k

end

end

table.remove(self.focuses, pos)

self.talkStart[focus] = nil

closeShopWindow(focus) --Even if it can not exist, we need to prevent it.

self:updateFocus()

else

closeShopWindow(focus)

self:changeFocus(0)

end

end

-- Returns the callback function with the specified id or nil if no such callback function exists.

function NpcHandler:getCallback(id)

local ret = nil

if(self.callbackFunctions ~= nil) then

ret = self.callbackFunctions[id]

end

return ret

end

-- Changes the callback function for the given id to callback.

function NpcHandler:setCallback(id, callback)

if(self.callbackFunctions ~= nil) then

self.callbackFunctions[id] = callback

end

end

-- Adds a module to this npchandler and inits it.

function NpcHandler:addModule(module)

if(self.modules == nil or module == nil) then

return false

end

module:init(self)

if(module.parseParameters ~= nil) then

module:parseParameters()

end

table.insert(self.modules, module)

return true

end

-- Calls the callback function represented by id for all modules added to this npchandler with the given arguments.

function NpcHandler:processModuleCallback(id, ...)

local ret = true

for i, module in pairs(self.modules) do

local tmpRet = true

if(id == CALLBACK_CREATURE_APPEAR and module.callbackOnCreatureAppear ~= nil) then

tmpRet = module:callbackOnCreatureAppear(unpack(arg))

elseif(id == CALLBACK_CREATURE_DISAPPEAR and module.callbackOnCreatureDisappear ~= nil) then

tmpRet = module:callbackOnCreatureDisappear(unpack(arg))

elseif(id == CALLBACK_CREATURE_SAY and module.callbackOnCreatureSay ~= nil) then

tmpRet = module:callbackOnCreatureSay(unpack(arg))

elseif(id == CALLBACK_PLAYER_ENDTRADE and module.callbackOnPlayerEndTrade ~= nil) then

tmpRet = module:callbackOnPlayerEndTrade(unpack(arg))

elseif(id == CALLBACK_PLAYER_CLOSECHANNEL and module.callbackOnPlayerCloseChannel ~= nil) then

tmpRet = module:callbackOnPlayerCloseChannel(unpack(arg))

elseif(id == CALLBACK_ONBUY and module.callbackOnBuy ~= nil) then

tmpRet = module:callbackOnBuy(unpack(arg))

elseif(id == CALLBACK_ONSELL and module.callbackOnSell ~= nil) then

tmpRet = module:callbackOnSell(unpack(arg))

elseif(id == CALLBACK_ONTHINK and module.callbackOnThink ~= nil) then

tmpRet = module:callbackOnThink(unpack(arg))

elseif(id == CALLBACK_GREET and module.callbackOnGreet ~= nil) then

tmpRet = module:callbackOnGreet(unpack(arg))

elseif(id == CALLBACK_FAREWELL and module.callbackOnFarewell ~= nil) then

tmpRet = module:callbackOnFarewell(unpack(arg))

elseif(id == CALLBACK_MESSAGE_DEFAULT and module.callbackOnMessageDefault ~= nil) then

tmpRet = module:callbackOnMessageDefault(unpack(arg))

elseif(id == CALLBACK_MODULE_RESET and module.callbackOnModuleReset ~= nil) then

tmpRet = module:callbackOnModuleReset(unpack(arg))

end

if(not tmpRet) then

ret = false

break

end

end

return ret

end

-- Returns the message represented by id.

function NpcHandler:getMessage(id)

local ret = nil

if(self.messages ~= nil) then

ret = self.messages[id]

end

return ret

end

-- Changes the default response message with the specified id to newMessage.

function NpcHandler:setMessage(id, newMessage)

if(self.messages ~= nil) then

self.messages[id] = newMessage

end

end

-- Translates all message tags found in msg using parseInfo

function NpcHandler:parseMessage(msg, parseInfo)

local ret = msg

for search, replace in pairs(parseInfo) do

ret = string.gsub(ret, search, replace)

end

return ret

end

-- Makes sure the npc un-focuses the currently focused player

function NpcHandler:unGreet(cid)

if(not self:isFocused(cid)) then

return

end

local callback = self:getCallback(CALLBACK_FAREWELL)

if(callback == nil or callback(cid)) then

if(self:processModuleCallback(CALLBACK_FAREWELL)) then

if(self.queue == nil or not self.queue:greetNext()) then

local msg = self:getMessage(MESSAGE_FAREWELL)

local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }

msg = self:parseMessage(msg, parseInfo)

self:say(msg, cid)

self:releaseFocus(cid)

self:say(msg)

end

end

end

end

-- Greets a new player.

function NpcHandler:greet(cid)

if(cid ~= 0) then

local callback = self:getCallback(CALLBACK_GREET)

if(callback == nil or callback(cid)) then

if(self:processModuleCallback(CALLBACK_GREET, cid)) then

local msg = self:getMessage(MESSAGE_GREET)

local parseInfo = { [TAG_PLAYERNAME] = getCreatureName(cid) }

msg = self:parseMessage(msg, parseInfo)

self:say(msg)

self:addFocus(cid)

self:say(msg, cid)

end

end

end

end

-- Handles onCreatureAppear events. If you with to handle this yourself, please use the CALLBACK_CREATURE_APPEAR callback.

function NpcHandler:onCreatureAppear(cid)

local callback = self:getCallback(CALLBACK_CREATURE_APPEAR)

if(callback == nil or callback(cid)) then

if(self:processModuleCallback(CALLBACK_CREATURE_APPEAR, cid)) then

--

end

end

end

-- Handles onCreatureDisappear events. If you with to handle this yourself, please use the CALLBACK_CREATURE_DISAPPEAR callback.

function NpcHandler:onCreatureDisappear(cid)

local callback = self:getCallback(CALLBACK_CREATURE_DISAPPEAR)

if(callback == nil or callback(cid)) then

if(self:processModuleCallback(CALLBACK_CREATURE_DISAPPEAR, cid)) then

if(self:isFocused(cid)) then

self:unGreet(cid)

end

end

end

end

-- Handles onCreatureSay events. If you with to handle this yourself, please use the CALLBACK_CREATURE_SAY callback.

function NpcHandler:onCreatureSay(cid, class, msg)

local callback = self:getCallback(CALLBACK_CREATURE_SAY)

if(callback == nil or callback(cid, class, msg)) then

if(self:processModuleCallback(CALLBACK_CREATURE_SAY, cid, class, msg)) then

if(not self:isInRange(cid)) then

return

end

if(self.keywordHandler ~= nil) then

if((self:isFocused(cid) and (class == TALKTYPE_PRIVATE_PN or NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT)) or not self:isFocused(cid)) then

local ret = self.keywordHandler:processMessage(cid, msg)

if(not ret) then

local callback = self:getCallback(CALLBACK_MESSAGE_DEFAULT)

if(callback ~= nil and callback(cid, class, msg)) then

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

self.talkStart[cid] = os.time()

else

self.talkStart = os.time()

end

end

else

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

self.talkStart[cid] = os.time()

else

self.talkStart = os.time()

end

end

end

end

end

end

end

-- Handles onPlayerEndTrade events. If you wish to handle this yourself, use the CALLBACK_PLAYER_ENDTRADE callback.

function NpcHandler:onPlayerEndTrade(cid)

local callback = self:getCallback(CALLBACK_PLAYER_ENDTRADE)

if(callback == nil or callback(cid)) then

if(self:processModuleCallback(CALLBACK_PLAYER_ENDTRADE, cid, class, msg)) then

if(self:isFocused(cid)) then

local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }

local msg = self:parseMessage(self:getMessage(MESSAGE_ONCLOSESHOP), parseInfo)

self:say(msg, cid)

end

end

end

end

-- Handles onPlayerCloseChannel events. If you wish to handle this yourself, use the CALLBACK_PLAYER_CLOSECHANNEL callback.

function NpcHandler:onPlayerCloseChannel(cid)

local callback = self:getCallback(CALLBACK_PLAYER_CLOSECHANNEL)

if(callback == nil or callback(cid)) then

if(self:processModuleCallback(CALLBACK_PLAYER_CLOSECHANNEL, cid, class, msg)) then

if(self:isFocused(cid)) then

self:unGreet(cid)

end

end

end

end

-- Handles onBuy events. If you wish to handle this yourself, use the CALLBACK_ONBUY callback.

function NpcHandler:onBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks)

local callback = self:getCallback(CALLBACK_ONBUY)

if(callback == nil or callback(cid, itemid, subType, amount, ignoreCap, inBackpacks)) then

if(self:processModuleCallback(CALLBACK_ONBUY, cid, itemid, subType, amount, ignoreCap, inBackpacks)) then

--

end

end

end

-- Handles onSell events. If you wish to handle this yourself, use the CALLBACK_ONSELL callback.

function NpcHandler:onSell(cid, itemid, subType, amount, ignoreCap, inBackpacks)

local callback = self:getCallback(CALLBACK_ONSELL)

if(callback == nil or callback(cid, itemid, subType, amount, ignoreCap, inBackpacks)) then

if(self:processModuleCallback(CALLBACK_ONSELL, cid, itemid, subType, amount, ignoreCap, inBackpacks)) then

--

end

end

end

-- Handles onThink events. If you wish to handle this yourself, please use the CALLBACK_ONTHINK callback.

function NpcHandler:onThink()

local callback = self:getCallback(CALLBACK_ONTHINK)

if(callback == nil or callback()) then

if(NPCHANDLER_TALKDELAY == TALKDELAY_ONTHINK) then

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

for cid, talkDelay in pairs(self.talkDelay) do

if(talkDelay.time ~= nil and talkDelay.message ~= nil and os.time() >= talkDelay.time) then

selfSay(talkDelay.message, cid)

self.talkDelay[cid] = nil

end

end

elseif(self.talkDelay.time ~= nil and self.talkDelay.message ~= nil and os.time() >= self.talkDelay.time) then

selfSay(self.talkDelay.message)

self.talkDelay.time = nil

self.talkDelay.message = nil

end

end

if(self:processModuleCallback(CALLBACK_ONTHINK)) then

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

for pos, focus in pairs(self.focuses) do

if(focus ~= nil) then

if(not self:isInRange(focus)) then

self:onWalkAway(focus)

elseif((os.time() - self.talkStart[focus]) > self.idleTime) then

self:unGreet(focus)

else

self:updateFocus()

end

end

end

elseif(self.focuses ~= 0) then

if(not self:isInRange(self.focuses)) then

self:onWalkAway(self.focuses)

elseif(os.time()-self.talkStart > self.idleTime) then

self:unGreet(self.focuses)

else

self:updateFocus()

end

end

end

end

end

-- Tries to greet the player with the given cid.

function NpcHandler:onGreet(cid)

if(self:isInRange(cid)) then

if(NPCHANDLER_CONVBEHAVIOR == CONVERSATION_PRIVATE) then

if(not self:isFocused(cid)) then

self:greet(cid)

return

end

elseif(NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT) then

if(self.focuses == 0) then

self:greet(cid)

elseif(self.focuses == cid) then

local msg = self:getMessage(MESSAGE_ALREADYFOCUSED)

local parseInfo = { [TAG_PLAYERNAME] = getCreatureName(cid) }

msg = self:parseMessage(msg, parseInfo)

self:say(msg)

else

if(not self.queue:isInQueue(cid)) then

self.queue:push(cid)

end

local msg = self:getMessage(MESSAGE_PLACEDINQUEUE)

local parseInfo = { [TAG_PLAYERNAME] = getCreatureName(cid), [TAG_QUEUESIZE] = self.queue:getSize() }

msg = self:parseMessage(msg, parseInfo)

self:say(msg)

end

end

end

end

-- Simply calls the underlying unGreet function.

function NpcHandler:onFarewell(cid)

self:unGreet(cid)

end

-- Should be called on this npc's focus if the distance to focus is greater then talkRadius.

function NpcHandler:onWalkAway(cid)

if(self:isFocused(cid)) then

local callback = self:getCallback(CALLBACK_CREATURE_DISAPPEAR)

if(callback == nil or callback(cid)) then

if(self:processModuleCallback(CALLBACK_CREATURE_DISAPPEAR, cid)) then

if(self.queue == nil or not self.queue:greetNext()) then

local msg = self:getMessage(MESSAGE_WALKAWAY)

local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }

msg = self:parseMessage(msg, parseInfo)

self:say(msg, cid)

self:releaseFocus(cid)

self:say(msg)

end

end

end

end

end

-- Returns true if cid is within the talkRadius of this npc.

function NpcHandler:isInRange(cid)

local distance = getDistanceBetween(getCreaturePosition(getNpcCid()), getCreaturePosition(cid))

if(distance == -1) then

return false

end

return (distance <= self.talkRadius)

end

-- Resets the npc into it's initial state (in regard of the keyrodhandler).

-- All modules are also receiving a reset call through their callbackOnModuleReset function.

function NpcHandler:resetNpc()

if(self:processModuleCallback(CALLBACK_MODULE_RESET)) then

self.keywordHandler:reset()

end

end

-- Makes the npc represented by this instance of NpcHandler say something.

-- This implements the currently set type of talkdelay.

-- shallDelay is a boolean value. If it is false, the message is not delayed. Default value is false.

function NpcHandler:say(message, focus, shallDelay)

local shallDelay = shallDelay or false

if(NPCHANDLER_TALKDELAY == TALKDELAY_NONE or not shallDelay) then

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

selfSay(message, focus)

return

else

selfSay(message)

return

end

end

-- TODO: Add an event handling method for delayed messages

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

self.talkDelay[focus] = {

message = message,

time = os.time() + self.talkDelayTime,

}

else

self.talkDelay = {

message = message,

time = os.time() + self.talkDelayTime

}

end

end

end

modules

-- Advanced NPC System (Created by Jiddo),

-- Modified by Talaturen.

-- Modified by Elf.

if(Modules == nil) then

-- Constants used to separate buying from selling.

SHOPMODULE_SELL_ITEM = 1

SHOPMODULE_BUY_ITEM = 2

SHOPMODULE_BUY_ITEM_CONTAINER = 3

-- Constants used for shop mode. Notice: addBuyableItemContainer is working on all modes

SHOPMODULE_MODE_TALK = 1 -- Old system used before Tibia 8.2: sell/buy item name

SHOPMODULE_MODE_TRADE = 2 -- Trade window system introduced in Tibia 8.2

SHOPMODULE_MODE_BOTH = 3 -- Both working at one time

-- Used in shop mode

SHOPMODULE_MODE = SHOPMODULE_MODE_BOTH

-- Constants used for outfit giving mode

OUTFITMODULE_FUNCTION_OLD = doPlayerAddOutfit -- Gives outfit through look type

OUTFITMODULE_FUNCTION_NEW = doPlayerAddOutfitId -- Gives outfit through outfit id

-- Used in outfit module

OUTFITMODULE_FUNCTION = OUTFITMODULE_FUNCTION_NEW

if(OUTFITMODULE_FUNCTION == nil) then

OUTFITMODULE_FUNCTION = OUTFITMODULE_FUNCTION_OLD

end

Modules = {

parseableModules = {}

}

StdModule = {}

-- These callback function must be called with parameters.npcHandler = npcHandler in the parameters table or they will not work correctly.

-- Notice: The members of StdModule have not yet been tested. If you find any bugs, please report them to me.

-- Usage:

-- keywordHandler:addKeyword({'offer'}, StdModule.say, {npcHandler = npcHandler, text = 'I sell many powerful melee weapons.'})

function StdModule.say(cid, message, keywords, parameters, node)

local npcHandler = parameters.npcHandler

if(npcHandler == nil) then

error('StdModule.say called without any npcHandler instance.')

end

local onlyFocus = (parameters.onlyFocus == nil or parameters.onlyFocus == true)

if(not npcHandler:isFocused(cid) and onlyFocus) then

return false

end

local parseInfo = {[TAG_PLAYERNAME] = getCreatureName(cid)}

npcHandler:say(npcHandler:parseMessage(parameters.text or parameters.message, parseInfo), cid, parameters.publicize and true)

if(parameters.reset == true) then

npcHandler:resetNpc()

elseif(parameters.moveup ~= nil and type(parameters.moveup) == 'number') then

npcHandler.keywordHandler:moveUp(parameters.moveup)

end

return true

end

--Usage:

-- local node1 = keywordHandler:addKeyword({'promot'}, StdModule.say, {npcHandler = npcHandler, text = 'I can promote you for 20000 brozne coins. Do you want me to promote you?'})

-- node1:addChildKeyword({'yes'}, StdModule.promotePlayer, {npcHandler = npcHandler, cost = 20000, promotion = 1, level = 20}, text = 'Congratulations! You are now promoted.')

-- node1:addChildKeyword({'no'}, StdModule.say, {npcHandler = npcHandler, text = 'Alright then, come back when you are ready.'}, reset = true)

function StdModule.promotePlayer(cid, message, keywords, parameters, node)

local npcHandler = parameters.npcHandler

if(npcHandler == nil) then

error('StdModule.promotePlayer called without any npcHandler instance.')

end

if(not npcHandler:isFocused(cid)) then

return false

end

if(isPlayerPremiumCallback(cid) or not getBooleanFromString(getConfigValue('premiumForPromotion')) or not(parameters.premium)) then

if(getPlayerPromotionLevel(cid) >= parameters.promotion) then

npcHandler:say('You are already promoted!', cid)

elseif(getPlayerLevel(cid) < parameters.level) then

npcHandler:say('I am sorry, but I can only promote you once you have reached level ' .. parameters.level .. '.', cid)

elseif(not doPlayerRemoveMoney(cid, parameters.cost)) then

npcHandler:say('You do not have enough money!', cid)

else

setPlayerPromotionLevel(cid, parameters.promotion)

npcHandler:say(parameters.text, cid)

end

else

npcHandler:say("You need a premium account in order to get promoted.", cid)

end

npcHandler:resetNpc()

return true

end

function StdModule.learnSpell(cid, message, keywords, parameters, node)

local npcHandler = parameters.npcHandler

if(npcHandler == nil) then

error('StdModule.learnSpell called without any npcHandler instance.')

end

if(not npcHandler:isFocused(cid)) then

return false

end

if(isPlayerPremiumCallback(cid) or not(parameters.premium)) then

if(getPlayerLearnedInstantSpell(cid, parameters.spellName)) then

npcHandler:say('You already know this spell.', cid)

elseif(getPlayerLevel(cid) < parameters.level) then

npcHandler:say('You need to obtain a level of ' .. parameters.level .. ' or higher to be able to learn ' .. parameters.spellName .. '.', cid)

elseif(getPlayerVocation(cid) ~= parameters.vocation and getPlayerVocation(cid) ~= parameters.vocation + 4 and vocation ~= 9) then

npcHandler:say('This spell is not for your vocation', cid)

elseif(not doPlayerRemoveMoney(cid, parameters.price)) then

npcHandler:say('You do not have enough money, this spell costs ' .. parameters.price .. ' gold coins.', cid)

else

npcHandler:say('You have learned ' .. parameters.spellName .. '.', cid)

playerLearnInstantSpell(cid, parameters.spellName)

end

else

npcHandler:say('You need a premium account in order to buy ' .. parameters.spellName .. '.', cid)

end

npcHandler:resetNpc()

return true

end

function StdModule.bless(cid, message, keywords, parameters, node)

local npcHandler = parameters.npcHandler

if(npcHandler == nil) then

error('StdModule.bless called without any npcHandler instance.')

end

if(not getBooleanFromString(getConfigValue('blessings'))) then

npcHandler:say("Sorry, but Gods moved back my permission to bless anyone.", cid)

return false

end

if(not npcHandler:isFocused(cid)) then

return false

end

if(isPlayerPremiumCallback(cid) or not getBooleanFromString(getConfigValue('blessingsOnlyPremium')) or not parameters.premium) then

local price = parameters.baseCost

if(getPlayerLevel(cid) > parameters.startLevel) then

price = (price + ((math.min(parameters.endLevel, getPlayerLevel(cid)) - parameters.startLevel) * parameters.levelCost))

end

if(getPlayerBlessing(cid, parameters.number)) then

npcHandler:say("Gods have already blessed you with this blessing!", cid)

elseif(not doPlayerRemoveMoney(cid, price)) then

npcHandler:say("You don't have enough money for blessing.", cid)

else

npcHandler:say("You have been blessed by one of the five gods!", cid)

doPlayerAddBlessing(cid, parameters.number)

end

else

npcHandler:say('You need a premium account in order to be blessed.', cid)

end

npcHandler:resetNpc()

return true

end

function StdModule.travel(cid, message, keywords, parameters, node)

local npcHandler = parameters.npcHandler

if(npcHandler == nil) then

error('StdModule.travel called without any npcHandler instance.')

end

if(not npcHandler:isFocused(cid)) then

return false

end

local storage, pzLocked = parameters.storageValue or (EMPTY_STORAGE + 1), parameters.allowLocked or false

if(parameters.premium and not isPlayerPremiumCallback(cid)) then

npcHandler:say('I can only allow premium players to travel with me.', cid)

elseif(parameters.level ~= nil and getPlayerLevel(cid) < parameters.level) then

npcHandler:say('You must reach level ' .. parameters.level .. ' before I can let you go there.', cid)

elseif(parameters.storageId ~= nil and getPlayerStorageValue(cid, parameters.storageId) < storage) then

npcHandler:say(parameters.storageInfo or 'You may not travel there!', cid)

elseif(not pzLocked and isPlayerPzLocked(cid)) then

npcHandler:say('Get out of there with this blood!', cid)

elseif(not doPlayerRemoveMoney(cid, parameters.cost)) then

npcHandler:say('You do not have enough money.', cid)

else

npcHandler:say('It was a pleasure doing business with you.', cid)

npcHandler:releaseFocus(cid)

doTeleportThing(cid, parameters.destination, false)

doSendMagicEffect(parameters.destination, CONST_ME_TELEPORT)

end

npcHandler:resetNpc()

return true

end

FocusModule = {

npcHandler = nil

}

-- Creates a new instance of FocusModule without an associated NpcHandler.

function FocusModule:new()

local obj = {}

setmetatable(obj, self)

self.__index = self

return obj

end

-- Inits the module and associates handler to it.

function FocusModule:init(handler)

self.npcHandler = handler

for i, word in pairs(FOCUS_GREETWORDS) do

local obj = {}

table.insert(obj, word)

obj.callback = FOCUS_GREETWORDS.callback or FocusModule.messageMatcher

handler.keywordHandler:addKeyword(obj, FocusModule.onGreet, {module = self})

end

for i, word in pairs(FOCUS_FAREWELLWORDS) do

local obj = {}

table.insert(obj, word)

obj.callback = FOCUS_FAREWELLWORDS.callback or FocusModule.messageMatcher

handler.keywordHandler:addKeyword(obj, FocusModule.onFarewell, {module = self})

end

end

-- Greeting callback function.

function FocusModule.onGreet(cid, message, keywords, parameters)

parameters.module.npcHandler:onGreet(cid)

return true

end

-- UnGreeting callback function.

function FocusModule.onFarewell(cid, message, keywords, parameters)

if(not parameters.module.npcHandler:isFocused(cid)) then

return false

end

parameters.module.npcHandler:onFarewell(cid)

return true

end

-- Custom message matching callback function for greeting messages.

function FocusModule.messageMatcher(keywords, message)

local spectators = getSpectators(getCreaturePosition(getNpcId()), 7, 7)

for i, word in pairs(keywords) do

if(type(word) == 'string') then

if(string.find(message, word) and not string.find(message, '[%w+]' .. word) and not string.find(message, word .. '[%w+]')) then

if(string.find(message, getCreatureName(getNpcId()))) then

return true

end

for i, uid in ipairs(spectators) do

if(string.find(message, getCreatureName(uid))) then

return false

end

end

return true

end

end

end

return false

end

KeywordModule = {

npcHandler = nil

}

-- Add it to the parseable module list.

Modules.parseableModules['module_keywords'] = KeywordModule

function KeywordModule:new()

local obj = {}

setmetatable(obj, self)

self.__index = self

return obj

end

function KeywordModule:init(handler)

self.npcHandler = handler

end

-- Parses all known parameters.

function KeywordModule:parseParameters()

local ret = NpcSystem.getParameter('keywords')

if(ret ~= nil) then

self:parseKeywords(ret)

end

end

function KeywordModule:parseKeywords(data)

local n = 1

for keys in string.gmatch(data, '[^;]+') do

local i = 1

local keywords = {}

for temp in string.gmatch(keys, '[^,]+') do

table.insert(keywords, temp)

i = i + 1

end

if(i ~= 1) then

local reply = NpcSystem.getParameter('keyword_reply' .. n)

if(reply ~= nil) then

self:addKeyword(keywords, reply)

else

print('[Warning] NpcSystem:', 'Parameter \'' .. 'keyword_reply' .. n .. '\' missing. Skipping...')

end

else

print('[Warning] NpcSystem:', 'No keywords found for keyword set #' .. n .. '. Skipping...')

end

n = n + 1

end

end

function KeywordModule:addKeyword(keywords, reply)

self.npcHandler.keywordHandler:addKeyword(keywords, StdModule.say, {npcHandler = self.npcHandler, onlyFocus = true, text = reply, reset = true})

end

TravelModule = {

npcHandler = nil,

destinations = nil,

yesNode = nil,

noNode = nil,

}

-- Add it to the parseable module list.

Modules.parseableModules['module_travel'] = TravelModule

function TravelModule:new()

local obj = {}

setmetatable(obj, self)

self.__index = self

return obj

end

function TravelModule:init(handler)

self.npcHandler = handler

self.yesNode = KeywordNode:new(SHOP_YESWORD, TravelModule.onConfirm, {module = self})

self.noNode = KeywordNode:new(SHOP_NOWORD, TravelModule.onDecline, {module = self})

self.destinations = {}

end

-- Parses all known parameters.

function TravelModule:parseParameters()

local ret = NpcSystem.getParameter('travel_destinations')

if(ret ~= nil) then

self:parseDestinations(ret)

for _, word in ipairs({'destination', 'list', 'where', 'travel'}) do

self.npcHandler.keywordHandler:addKeyword({word}, TravelModule.listDestinations, {module = self})

end

end

end

function TravelModule:parseDestinations(data)

for destination in string.gmatch(data, '[^;]+') do

local i, name, pos, cost, premium, level, storage = 1, nil, {x = nil, y = nil, z = nil}, nil, false

for tmp in string.gmatch(destination, '[^,]+') do

if(i == 1) then

name = tmp

elseif(i == 2) then

pos.x = tonumber(tmp)

elseif(i == 3) then

pos.y = tonumber(tmp)

elseif(i == 4) then

pos.z = tonumber(tmp)

elseif(i == 5) then

cost = tonumber(tmp)

elseif(i == 6) then

premium = getBooleanFromString(tmp)

else

print('[Warning] NpcSystem:', 'Unknown parameter found in travel destination parameter.', tmp, destination)

end

i = i + 1

end

if(name ~= nil and pos.x ~= nil and pos.y ~= nil and pos.z ~= nil and cost ~= nil) then

self:addDestination(name, pos, cost, premium)

else

print('[Warning] NpcSystem:', 'Parameter(s) missing for travel destination:', name, pos, cost, premium)

end

end

end

function TravelModule:addDestination(name, position, price, premium)

table.insert(self.destinations, name)

local parameters = {

cost = price,

destination = position,

premium = premium,

module = self

}

local keywords, bringwords = {}, {}

table.insert(keywords, name)

table.insert(bringwords, 'bring me to ' .. name)

self.npcHandler.keywordHandler:addKeyword(bringwords, TravelModule.bring, parameters)

local node = self.npcHandler.keywordHandler:addKeyword(keywords, TravelModule.travel, parameters)

node:addChildKeywordNode(self.yesNode)

node:addChildKeywordNode(self.noNode)

end

function TravelModule.travel(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

module.npcHandler:say('Do you want to travel to ' .. keywords[1] .. ' for ' .. parameters.cost .. ' gold coins?', cid)

return true

end

function TravelModule.onConfirm(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

local parent = node:getParent():getParameters()

if(isPlayerPremiumCallback(cid) or not parent.premium) then

if(not isPlayerPzLocked(cid)) then

if(doPlayerRemoveMoney(cid, parent.cost)) then

module.npcHandler:say('It was a pleasure doing business with you.', cid)

module.npcHandler:releaseFocus(cid)

doTeleportThing(cid, parent.destination, true)

doSendMagicEffect(parent.destination, CONST_ME_TELEPORT)

else

module.npcHandler:say('You do not have enough money.', cid)

end

else

module.npcHandler:say('Get out of there with this blood!', cid)

end

else

modulenpcHandler:say('I can only allow premium players to travel there.', cid)

end

module.npcHandler:resetNpc()

return true

end

-- onDecline keyword callback function. Generally called when the player sais 'no' after wanting to buy an item.

function TravelModule.onDecline(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

module.npcHandler:say(module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_DECLINE), {[TAG_PLAYERNAME] = getCreatureName(cid)}), cid)

module.npcHandler:resetNpc()

return true

end

function TravelModule.bring(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

if((isPlayerPremiumCallback(cid) or not parameters.premium) and not isPlayerPzLocked(cid) and doPlayerRemoveMoney(cid, parameters.cost)) then

module.npcHandler:say('Sure!', cid)

module.npcHandler:releaseFocus(cid)

doTeleportThing(cid, parameters.destination, false)

doSendMagicEffect(parameters.destination, CONST_ME_TELEPORT)

end

module.npcHandler:releaseFocus(cid)

return true

end

function TravelModule.listDestinations(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

local msg = nil

for _, destination in ipairs(module.destinations) do

if(msg ~= nil) then

msg = msg .. ", "

else

msg = ""

end

msg = msg .. "{" .. destination .. "}"

end

module.npcHandler:say(msg .. ".", cid)

module.npcHandler:resetNpc()

return true

end

OutfitModule = {

npcHandler = nil,

outfits = nil,

yesNode = nil,

noNode = nil,

}

-- Add it to the parseable module list.

Modules.parseableModules['module_outfit'] = OutfitModule

function OutfitModule:new()

if(OUTFITMODULE_FUNCTION == nil) then

return nil

end

local obj = {}

setmetatable(obj, self)

self.__index = self

return obj

end

function OutfitModule:init(handler)

self.npcHandler = handler

self.yesNode = KeywordNode:new(SHOP_YESWORD, OutfitModule.onConfirm, {module = self})

self.noNode = KeywordNode:new(SHOP_NOWORD, OutfitModule.onDecline, {module = self})

self.outfits = {}

end

-- Parses all known parameters.

function OutfitModule:parseParameters()

local ret = NpcSystem.getParameter('outfits')

if(ret ~= nil) then

self:parseKeywords(ret)

for _, word in ipairs({'outfits', 'addons'}) do

self.npcHandler.keywordHandler:addKeyword({word}, OutfitModule.listOutfits, {module = self})

end

end

end

function OutfitModule:parseKeywords(data)

local n = 1

for outfit in string.gmatch(data, '[^;]+') do

local i, keywords = 1, {}

for tmp in string.gmatch(outfit, '[^,]+') do

table.insert(keywords, tmp)

i = i + 1

end

if(i > 0) then

local ret = NpcSystem.getParameter('outfit' .. n)

if(ret ~= nil) then

self:parseList(keywords, ret)

else

print('[Warning] NpcSystem:', 'Missing \'outfit' .. n .. '\' parameter, skipping...')

end

else

print('[Warning] NpcSystem:', 'No keywords found for outfit set #' .. n .. ', skipping...')

end

n = n + 1

end

end

function OutfitModule:parseList(keywords, data)

local outfit, items = nil, {}

for list in string.gmatch(data, '[^;]+') do

local a, b, c, d, e = nil, nil, nil, nil, 1

for tmp in string.gmatch(list, '[^,]+') do

if(e == 1) then

a = tmp

elseif(e == 2) then

b = tmp

elseif(e == 3) then

c = tmp

elseif(e == 4) then

d = tmp

else

print('[Warning] NpcSystem:', 'Unknown parameter found in outfit list while parsing ' .. (outfit == nil and 'outfit' or 'item') .. '.', tmp, list)

end

e = e + 1

end

if(outfit == nil) then

outfit = {tonumber(a), tonumber(b), getBooleanFromString©, d}

elseif(a ~= nil) then

local tmp = tonumber(a)

if((tmp ~= nil or tostring(a) == "money") and b ~= nil and c ~= nil) then

a = tmp or 20000

tmp = tonumber(d)

if(tmp == nil) then

tmp = -1

end

items[a] = {b, tmp, c}

else

print('[Warning] NpcSystem:', 'Missing parameter(s) for outfit items.', b, c, d)

end

else

print('[Warning] NpcSystem:', 'Missing base parameter for outfit items.', a)

end

end

if(type(outfit) == 'table') then

local tmp = true

for i = 1, 2 do

if(outfit == nil) then

tmp = false

break

end

end

if(tmp and table.maxn(items) > 0) then

self:addOutfit(keywords, outfit, items)

else

print('[Warning] NpcSystem:', 'Invalid outfit, addon or empty items pool.', data)

end

end

end

function OutfitModule:addOutfit(keywords, outfit, items)

table.insert(self.outfits, keywords[1])

local parameters = {

outfit = outfit[1],

addon = outfit[2],

premium = outfit[3],

gender = nil,

items = items,

module = self

}

if(outfit[4] ~= nil) then

local tmp = string.lower(tostring(outfit[5]))

if(tmp == 'male' or tmp == '1') then

parameters.gender = 1

elseif(tmp == 'female' or tmp == '0') then

parameters.gender = 0

end

end

for i, name in pairs(keywords) do

local words = {}

table.insert(words, name)

local node = self.npcHandler.keywordHandler:addKeyword(words, OutfitModule.obtain, parameters)

node:addChildKeywordNode(self.yesNode)

node:addChildKeywordNode(self.noNode)

end

end

function OutfitModule.obtain(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

local items = nil

for k, v in pairs(parameters.items) do

if(v[1] ~= "storageset") then

if(items ~= nil) then

items = items .. ", "

else

items = ""

end

if(tonumber(v[1]) ~= nil and tonumber(v[1]) > 1) then

items = items .. v[1] .. " "

end

items = items .. v[3]

end

end

module.npcHandler:say('Do you want ' .. keywords[1] .. ' ' .. (addon == 0 and "outfit" or "addon") .. ' for ' .. items .. '?', cid)

return true

end

function OutfitModule.onConfirm(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

local parent = node:getParent():getParameters()

if(isPlayerPremiumCallback(cid) or not parent.premium) then

if(not canPlayerWearOutfitId(cid, parent.outfit, parent.addon)) then

if(parent.addon == 0 or canPlayerWearOutfitId(cid, parent.outfit)) then

if(parent.gender == nil or parent.gender == getPlayerSex(cid)) then

local found = true

for k, v in pairs(parent.items) do

local tmp = tonumber(v[1])

if(tmp == nil) then

if(v[1] == "storagecheck") then

if(getCreatureStorage(cid, k) < v[2]) then

found = false

end

elseif(v[1] == "outfitid") then

if(not canPlayerWearOutfitId(cid, k, v[2])) then

found = false

end

elseif(v[1] == "outfit") then

if(not canPlayerWearOutfit(cid, k, v[2])) then

found = false

end

else

found = false

end

elseif(k == 20000) then

if(getPlayerMoney(cid) < tmp) then

found = false

end

elseif(getPlayerItemCount(cid, k, v[2]) < tmp) then

found = false

end

if(not found) then

break

end

end

if(found) then

for k, v in pairs(parent.items) do

if(tonumber(v[1]) ~= nil) then

if(k == 20000) then

doPlayerRemoveMoney(cid, v[1])

else

doPlayerRemoveItem(cid, k, v[1], v[2])

end

elseif(v[1] == "storageset") then

doCreatureSetStorage(cid, k, v[2])

end

end

module.npcHandler:say('It was a pleasure to dress you.', cid)

OUTFITMODULE_FUNCTION(cid, parent.outfit, parent.addon)

doPlayerSetStorageValue(cid, parent.storageId, storage)

else

module.npcHandler:say('You don\'t have these items!', cid)

end

else

module.npcHandler:say('Sorry, this ' .. (parent.addon == 0 and 'outfit' or 'addon') .. ' is not for your gender.', cid)

end

else

module.npcHandler:say('I will not dress you with addon of outfit you cannot wear!', cid)

end

else

module.npcHandler:say('You alrady have this ' .. (parent.addon == 0 and 'outfit' or 'addon') .. '!', cid)

end

else

module.npcHandler:say('Sorry, I dress only premium players.', cid)

end

module.npcHandler:resetNpc()

return true

end

-- onDecline keyword callback function. Generally called when the player sais 'no' after wanting to buy an item.

function OutfitModule.onDecline(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

module.npcHandler:say(module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_DECLINE), {[TAG_PLAYERNAME] = getCreatureName(cid)}), cid)

module.npcHandler:resetNpc()

return true

end

function OutfitModule.listOutfits(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

local msg = nil

if(table.maxn(module.outfits) > 0) then

for _, outfit in ipairs(module.outfits) do

if(msg ~= nil) then

msg = msg .. ", "

else

msg = "I can dress you into "

end

msg = msg .. "{" .. outfit .. "}"

end

else

msg = "Sorry, I have nothing to offer right now."

end

module.npcHandler:say(msg .. ".", cid)

module.npcHandler:resetNpc()

return true

end

ShopModule = {

npcHandler = nil,

yesNode = nil,

noNode = nil,

noText = '',

maxCount = 100,

amount = 0

}

-- Add it to the parseable module list.

Modules.parseableModules['module_shop'] = ShopModule

-- Creates a new instance of ShopModule

function ShopModule:new()

local obj = {}

setmetatable(obj, self)

self.__index = self

return obj

end

-- Parses all known parameters.

function ShopModule:parseParameters()

local ret = NpcSystem.getParameter('shop_buyable')

if(ret ~= nil) then

self:parseBuyable(ret)

end

local ret = NpcSystem.getParameter('shop_sellable')

if(ret ~= nil) then

self:parseSellable(ret)

end

local ret = NpcSystem.getParameter('shop_buyable_containers')

if(ret ~= nil) then

self:parseBuyableContainers(ret)

end

end

-- Parse a string contaning a set of buyable items.

function ShopModule:parseBuyable(data)

for item in string.gmatch(data, '[^;]+') do

local i = 1

local name = nil

local itemid = nil

local cost = nil

local subType = nil

local realName = nil

for temp in string.gmatch(item, '[^,]+') do

if(i == 1) then

name = temp

elseif(i == 2) then

itemid = tonumber(temp)

elseif(i == 3) then

cost = tonumber(temp)

elseif(i == 4) then

subType = tonumber(temp)

elseif(i == 5) then

realName = temp

else

print('[Warning] NpcSystem:', 'Unknown parameter found in buyable items parameter.', temp, item)

end

i = i + 1

end

if(SHOPMODULE_MODE == SHOPMODULE_MODE_TRADE) then

if(itemid ~= nil and cost ~= nil) then

if((isItemRune(itemid) or isItemFluidContainer(itemid)) and subType == nil) then

print('[Warning] NpcSystem:', 'SubType missing for parameter item:', item)

else

self:addBuyableItem(nil, itemid, cost, subType, realName)

end

else

print('[Warning] NpcSystem:', 'Parameter(s) missing for item:', itemid, cost)

end

else

if(name ~= nil and itemid ~= nil and cost ~= nil) then

if((isItemRune(itemid) or isItemFluidContainer(itemid)) and subType == nil) then

print('[Warning] NpcSystem:', 'SubType missing for parameter item:', item)

else

local names = {}

table.insert(names, name)

self:addBuyableItem(names, itemid, cost, subType, realName)

end

else

print('[Warning] NpcSystem:', 'Parameter(s) missing for item:', name, itemid, cost)

end

end

end

end

-- Parse a string contaning a set of sellable items.

function ShopModule:parseSellable(data)

for item in string.gmatch(data, '[^;]+') do

local i = 1

local name = nil

local itemid = nil

local cost = nil

local realName = nil

for temp in string.gmatch(item, '[^,]+') do

if(i == 1) then

name = temp

elseif(i == 2) then

itemid = tonumber(temp)

elseif(i == 3) then

cost = tonumber(temp)

elseif(i == 4) then

realName = temp

else

print('[Warning] NpcSystem:', 'Unknown parameter found in sellable items parameter.', temp, item)

end

i = i + 1

end

if(SHOPMODULE_MODE == SHOPMODULE_MODE_TRADE) then

if(itemid ~= nil and cost ~= nil) then

self:addSellableItem(nil, itemid, cost, realName)

else

print('[Warning] NpcSystem:', 'Parameter(s) missing for item:', itemid, cost)

end

else

if(name ~= nil and itemid ~= nil and cost ~= nil) then

local names = {}

table.insert(names, name)

self:addSellableItem(names, itemid, cost, realName)

else

print('[Warning] NpcSystem:', 'Parameter(s) missing for item:', name, itemid, cost)

end

end

end

end

-- Parse a string contaning a set of buyable items.

function ShopModule:parseBuyableContainers(data)

for item in string.gmatch(data, '[^;]+') do

local i = 1

local name = nil

local container = nil

local itemid = nil

local cost = nil

local subType = nil

local realName = nil

for temp in string.gmatch(item, '[^,]+') do

if(i == 1) then

name = temp

elseif(i == 2) then

itemid = tonumber(temp)

elseif(i == 3) then

itemid = tonumber(temp)

elseif(i == 4) then

cost = tonumber(temp)

elseif(i == 5) then

subType = tonumber(temp)

elseif(i == 6) then

realName = temp

else

print('[Warning] NpcSystem:', 'Unknown parameter found in buyable items parameter.', temp, item)

end

i = i + 1

end

if(name ~= nil and container ~= nil and itemid ~= nil and cost ~= nil) then

if((isItemRune(itemid) or isItemFluidContainer(itemid)) and subType == nil) then

print('[Warning] NpcSystem:', 'SubType missing for parameter item:', item)

else

local names = {}

table.insert(names, name)

self:addBuyableItemContainer(names, container, itemid, cost, subType, realName)

end

else

print('[Warning] NpcSystem:', 'Parameter(s) missing for item:', name, container, itemid, cost)

end

end

end

-- Initializes the module and associates handler to it.

function ShopModule:init(handler)

self.npcHandler = handler

self.yesNode = KeywordNode:new(SHOP_YESWORD, ShopModule.onConfirm, {module = self})

self.noNode = KeywordNode:new(SHOP_NOWORD, ShopModule.onDecline, {module = self})

self.noText = handler:getMessage(MESSAGE_DECLINE)

if(SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK) then

for i, word in pairs(SHOP_TRADEREQUEST) do

local obj = {}

table.insert(obj, word)

obj.callback = SHOP_TRADEREQUEST.callback or ShopModule.messageMatcher

handler.keywordHandler:addKeyword(obj, ShopModule.requestTrade, {module = self})

end

end

end

-- Custom message matching callback function for requesting trade messages.

function ShopModule.messageMatcher(keywords, message)

for i, word in pairs(keywords) do

if(type(word) == 'string') then

if string.find(message, word) and not string.find(message, '[%w+]' .. word) and not string.find(message, word .. '[%w+]') then

return true

end

end

end

return false

end

-- Resets the module-specific variables.

function ShopModule:reset()

self.amount = 0

end

-- Function used to match a number value from a string.

function ShopModule:getCount(message)

local ret = 1

local b, e = string.find(message, PATTERN_COUNT)

if b ~= nil and e ~= nil then

ret = tonumber(string.sub(message, b, e))

end

if(ret <= 0) then

ret = 1

elseif(ret > self.maxCount) then

ret = self.maxCount

end

return ret

end

-- Adds a new buyable item.

-- names = A table containing one or more strings of alternative names to this item. Used only for old buy/sell system.

-- itemid = The itemid of the buyable item

-- cost = The price of one single item

-- subType - The subType of each rune or fluidcontainer item. Can be left out if it is not a rune/fluidcontainer. Default value is 1.

-- realName - The real, full name for the item. Will be used as ITEMNAME in MESSAGE_ONBUY and MESSAGE_ONSELL if defined. Default value is nil (getItemNameById will be used)

function ShopModule:addBuyableItem(names, itemid, cost, subType, realName)

if(SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK) then

if(self.npcHandler.shopItems[itemid] == nil) then

self.npcHandler.shopItems[itemid] = {buyPrice = -1, sellPrice = -1, subType = 1, realName = ""}

end

self.npcHandler.shopItems[itemid].buyPrice = cost

self.npcHandler.shopItems[itemid].realName = realName or getItemNameById(itemid)

self.npcHandler.shopItems[itemid].subType = subType or 1

end

if(names ~= nil and SHOPMODULE_MODE ~= SHOPMODULE_MODE_TRADE) then

local parameters = {

itemid = itemid,

cost = cost,

eventType = SHOPMODULE_BUY_ITEM,

module = self,

realName = realName or getItemNameById(itemid),

subType = subType or 1

}

for i, name in pairs(names) do

local keywords = {}

table.insert(keywords, 'buy')

table.insert(keywords, name)

local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters)

node:addChildKeywordNode(self.yesNode)

node:addChildKeywordNode(self.noNode)

end

end

end

-- Adds a new buyable container of items.

-- names = A table containing one or more strings of alternative names to this item.

-- container = Backpack, bag or any other itemid of container where bought items will be stored

-- itemid = The itemid of the buyable item

-- cost = The price of one single item

-- subType - The subType of each rune or fluidcontainer item. Can be left out if it is not a rune/fluidcontainer. Default value is 1.

-- realName - The real, full name for the item. Will be used as ITEMNAME in MESSAGE_ONBUY and MESSAGE_ONSELL if defined. Default value is nil (getItemNameById will be used)

function ShopModule:addBuyableItemContainer(names, container, itemid, cost, subType, realName)

if(names ~= nil) then

local parameters = {

container = container,

itemid = itemid,

cost = cost,

eventType = SHOPMODULE_BUY_ITEM_CONTAINER,

module = self,

realName = realName or getItemNameById(itemid),

subType = subType or 1

}

for i, name in pairs(names) do

local keywords = {}

table.insert(keywords, 'buy')

table.insert(keywords, name)

local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters)

node:addChildKeywordNode(self.yesNode)

node:addChildKeywordNode(self.noNode)

end

end

end

-- Adds a new sellable item.

-- names = A table containing one or more strings of alternative names to this item. Used only by old buy/sell system.

-- itemid = The itemid of the sellable item

-- cost = The price of one single item

-- realName - The real, full name for the item. Will be used as ITEMNAME in MESSAGE_ONBUY and MESSAGE_ONSELL if defined. Default value is nil (getItemNameById will be used)

function ShopModule:addSellableItem(names, itemid, cost, realName)

if(SHOPMODULE_MODE ~= SHOPMODULE_MODE_TALK) then

if(self.npcHandler.shopItems[itemid] == nil) then

self.npcHandler.shopItems[itemid] = {buyPrice = -1, sellPrice = -1, subType = 1, realName = ""}

end

self.npcHandler.shopItems[itemid].sellPrice = cost

self.npcHandler.shopItems[itemid].realName = realName or getItemNameById(itemid)

end

if(names ~= nil and SHOPMODULE_MODE ~= SHOPMODULE_MODE_TRADE) then

local parameters = {

itemid = itemid,

cost = cost,

eventType = SHOPMODULE_SELL_ITEM,

module = self,

realName = realName or getItemNameById(itemid)

}

for i, name in pairs(names) do

local keywords = {}

table.insert(keywords, 'sell')

table.insert(keywords, name)

local node = self.npcHandler.keywordHandler:addKeyword(keywords, ShopModule.tradeItem, parameters)

node:addChildKeywordNode(self.yesNode)

node:addChildKeywordNode(self.noNode)

end

end

end

-- onModuleReset callback function. Calls ShopModule:reset()

function ShopModule:callbackOnModuleReset()

self:reset()

return true

end

-- Callback onBuy() function. If you wish, you can change certain Npc to use your onBuy().

function ShopModule:callbackOnBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks)

if(self.npcHandler.shopItems[itemid] == nil) then

error("[shopModule.onBuy]", "items[itemid] == nil")

return false

end

if(self.npcHandler.shopItems[itemid].buyPrice == -1) then

error("[shopModule.onSell]", "Attempt to buy a non-buyable item")

return false

end

local backpack = 1988

local totalCost = amount * self.npcHandler.shopItems[itemid].buyPrice

if(inBackpacks) then

totalCost = totalCost + (math.max(1, math.floor(amount / getContainerCapById(backpack))) * 20)

end

local parseInfo = {

[TAG_PLAYERNAME] = getPlayerName(cid),

[TAG_ITEMCOUNT] = amount,

[TAG_TOTALCOST] = totalCost,

[TAG_ITEMNAME] = self.npcHandler.shopItems[itemid].realName

}

if(getPlayerMoney(cid) < totalCost) then

local msg = self.npcHandler:getMessage(MESSAGE_NEEDMONEY)

msg = self.npcHandler:parseMessage(msg, parseInfo)

doPlayerSendCancel(cid, msg)

return false

end

local subType = self.npcHandler.shopItems[itemid].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

local msg = self.npcHandler:getMessage(msgId)

parseInfo[TAG_ITEMCOUNT] = a

msg = self.npcHandler:parseMessage(msg, parseInfo)

doPlayerSendCancel(cid, msg)

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

self.npcHandler.talkStart[cid] = os.time()

else

self.npcHandler.talkStart = os.time()

end

if(a > 0) then

doPlayerRemoveMoney(cid, ((a * self.npcHandler.shopItems[itemid].buyPrice) + (b * 20)))

return true

end

return false

else

local msg = self.npcHandler:getMessage(MESSAGE_BOUGHT)

msg = self.npcHandler:parseMessage(msg, parseInfo)

doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, msg)

doPlayerRemoveMoney(cid, totalCost)

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

self.npcHandler.talkStart[cid] = os.time()

else

self.npcHandler.talkStart = os.time()

end

return true

end

end

-- Callback onSell() function. If you wish, you can change certain Npc to use your onSell().

function ShopModule:callbackOnSell(cid, itemid, subType, amount, ignoreCap, inBackpacks)

if(self.npcHandler.shopItems[itemid] == nil) then

error("[shopModule.onSell]", "items[itemid] == nil")

return false

end

if(self.npcHandler.shopItems[itemid].sellPrice == -1) then

error("[shopModule.onSell]", "Attempt to sell a non-sellable item")

return false

end

local parseInfo = {

[TAG_PLAYERNAME] = getPlayerName(cid),

[TAG_ITEMCOUNT] = amount,

[TAG_TOTALCOST] = amount * self.npcHandler.shopItems[itemid].sellPrice,

[TAG_ITEMNAME] = self.npcHandler.shopItems[itemid].realName

}

if(subType < 1) then

subType = -1

end

if(doPlayerRemoveItem(cid, itemid, amount, subType)) then

local msg = self.npcHandler:getMessage(MESSAGE_SOLD)

msg = self.npcHandler:parseMessage(msg, parseInfo)

doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, msg)

doPlayerAddMoney(cid, amount * self.npcHandler.shopItems[itemid].sellPrice)

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

self.npcHandler.talkStart[cid] = os.time()

else

self.npcHandler.talkStart = os.time()

end

return true

else

local msg = self.npcHandler:getMessage(MESSAGE_NEEDITEM)

msg = self.npcHandler:parseMessage(msg, parseInfo)

doPlayerSendCancel(cid, msg)

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

self.npcHandler.talkStart[cid] = os.time()

else

self.npcHandler.talkStart = os.time()

end

return false

end

end

-- Callback for requesting a trade window with the NPC.

function ShopModule.requestTrade(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

local itemWindow = {}

for itemid, attr in pairs(module.npcHandler.shopItems) do

local item = {id = itemid, buy = attr.buyPrice, sell = attr.sellPrice, subType = attr.subType, name = attr.realName}

table.insert(itemWindow, item)

end

if(itemWindow[1] == nil) then

local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }

local msg = module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_NOSHOP), parseInfo)

module.npcHandler:say(msg, cid)

return true

end

local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }

local msg = module.npcHandler:parseMessage(module.npcHandler:getMessage(MESSAGE_SENDTRADE), parseInfo)

openShopWindow(cid, itemWindow,

function(cid, itemid, subType, amount, ignoreCap, inBackpacks) module.npcHandler:onBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks) end,

function(cid, itemid, subType, amount, ignoreCap, inBackpacks) module.npcHandler:onSell(cid, itemid, subType, amount, ignoreCap, inBackpacks) end)

module.npcHandler:say(msg, cid)

return true

end

-- onConfirm keyword callback function. Sells/buys the actual item.

function ShopModule.onConfirm(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

local parentParameters = node:getParent():getParameters()

local parseInfo = {

[TAG_PLAYERNAME] = getPlayerName(cid),

[TAG_ITEMCOUNT] = module.amount,

[TAG_TOTALCOST] = parentParameters.cost * module.amount,

[TAG_ITEMNAME] = parentParameters.realName

}

if(parentParameters.eventType == SHOPMODULE_SELL_ITEM) then

local ret = doPlayerSellItem(cid, parentParameters.itemid, module.amount, parentParameters.cost * module.amount)

if(ret) then

local msg = module.npcHandler:getMessage(MESSAGE_ONSELL)

msg = module.npcHandler:parseMessage(msg, parseInfo)

module.npcHandler:say(msg, cid)

else

local msg = module.npcHandler:getMessage(MESSAGE_MISSINGITEM)

msg = module.npcHandler:parseMessage(msg, parseInfo)

module.npcHandler:say(msg, cid)

end

elseif(parentParameters.eventType == SHOPMODULE_BUY_ITEM) then

local ret = doPlayerBuyItem(cid, parentParameters.itemid, module.amount, parentParameters.cost * module.amount, parentParameters.subType)

if(ret) then

if parentParameters.itemid == ITEM_PARCEL then

doPlayerBuyItem(cid, ITEM_LABEL, module.amount, 0, parentParameters.subType)

end

local msg = module.npcHandler:getMessage(MESSAGE_ONBUY)

msg = module.npcHandler:parseMessage(msg, parseInfo)

module.npcHandler:say(msg, cid)

else

local msg = module.npcHandler:getMessage(MESSAGE_MISSINGMONEY)

msg = module.npcHandler:parseMessage(msg, parseInfo)

module.npcHandler:say(msg, cid)

end

elseif(parentParameters.eventType == SHOPMODULE_BUY_ITEM_CONTAINER) then

local ret = doPlayerBuyItemContainer(cid, parentParameters.container, parentParameters.itemid, module.amount, parentParameters.cost * module.amount, parentParameters.subType)

if(ret) then

local msg = module.npcHandler:getMessage(MESSAGE_ONBUY)

msg = module.npcHandler:parseMessage(msg, parseInfo)

module.npcHandler:say(msg, cid)

else

local msg = module.npcHandler:getMessage(MESSAGE_MISSINGMONEY)

msg = module.npcHandler:parseMessage(msg, parseInfo)

module.npcHandler:say(msg, cid)

end

end

module.npcHandler:resetNpc()

return true

end

-- onDecliune keyword callback function. Generally called when the player sais 'no' after wanting to buy an item.

function ShopModule.onDecline(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

local parentParameters = node:getParent():getParameters()

local parseInfo = {

[TAG_PLAYERNAME] = getPlayerName(cid),

[TAG_ITEMCOUNT] = module.amount,

[TAG_TOTALCOST] = parentParameters.cost * module.amount,

[TAG_ITEMNAME] = parentParameters.realName

}

local msg = module.npcHandler:parseMessage(module.noText, parseInfo)

module.npcHandler:say(msg, cid)

module.npcHandler:resetNpc()

return true

end

-- tradeItem callback function. Makes the npc say the message defined by MESSAGE_BUY or MESSAGE_SELL

function ShopModule.tradeItem(cid, message, keywords, parameters, node)

local module = parameters.module

if(not module.npcHandler:isFocused(cid)) then

return false

end

local count = module:getCount(message)

module.amount = count

local parseInfo = {

[TAG_PLAYERNAME] = getPlayerName(cid),

[TAG_ITEMCOUNT] = module.amount,

[TAG_TOTALCOST] = parameters.cost * module.amount,

[TAG_ITEMNAME] = parameters.realName

}

if(parameters.eventType == SHOPMODULE_SELL_ITEM) then

local msg = module.npcHandler:getMessage(MESSAGE_SELL)

msg = module.npcHandler:parseMessage(msg, parseInfo)

module.npcHandler:say(msg, cid)

elseif(parameters.eventType == SHOPMODULE_BUY_ITEM) then

local msg = module.npcHandler:getMessage(MESSAGE_BUY)

msg = module.npcHandler:parseMessage(msg, parseInfo)

module.npcHandler:say(msg, cid)

elseif(parameters.eventType == SHOPMODULE_BUY_ITEM_CONTAINER) then

local msg = module.npcHandler:getMessage(MESSAGE_BUY)

msg = module.npcHandler:parseMessage(msg, parseInfo)

module.npcHandler:say(msg, cid)

end

return true

end

end

comedinhas, todos os npc nao vendem atraz do trade. Vou postar a pasta libs no topico la em cima.

Editado por Fabiano Alberto (veja o histórico de edições)

SE AJUDEI REP+ ;D, NÃO CUSTA NADA.

uRti.png

<a href="http://central.evenhost.net/aff.php?aff=020"><img src="http://i.imm.io/uRti.png" width="500" height="82" border="0"></a>

Link para o post
Compartilhar em outros sites

Uh... Acho que já sei o que é...

Coloca essa pasta nos npcs pra substitui tudo...

lib.rar

Bruno de Carvalho Câmara / Administrador TibiaKing

[email protected]


 

btn_donateCC_LG.gif

 

Em 26/12/2016 em 03:47, Spraypaint disse:

A força da alienação vem dessa fragilidade dos indivíduos, quando apenas conseguem identificar o que os separa e não o que os une.

-miltinho

 

wMwSJFE.png?1

 

Link para o post
Compartilhar em outros sites

Agora da o seguinte erro, o player fala trade e nao aparece nada, olha a imagem do erro\/

bug2e.png

SE AJUDEI REP+ ;D, NÃO CUSTA NADA.

uRti.png

<a href="http://central.evenhost.net/aff.php?aff=020"><img src="http://i.imm.io/uRti.png" width="500" height="82" border="0"></a>

Link para o post
Compartilhar em outros sites

que estranho, onde você conseguiu este servidor?

Bruno de Carvalho Câmara / Administrador TibiaKing

[email protected]


 

btn_donateCC_LG.gif

 

Em 26/12/2016 em 03:47, Spraypaint disse:

A força da alienação vem dessa fragilidade dos indivíduos, quando apenas conseguem identificar o que os separa e não o que os une.

-miltinho

 

wMwSJFE.png?1

 

Link para o post
Compartilhar em outros sites

esse ot eu tenho desde 2010 e nunca teve esse bug, so foi eu por em linux q começo a dar esse bug e o bug das vocações lá.

SE AJUDEI REP+ ;D, NÃO CUSTA NADA.

uRti.png

<a href="http://central.evenhost.net/aff.php?aff=020"><img src="http://i.imm.io/uRti.png" width="500" height="82" border="0"></a>

Link para o post
Compartilhar em outros sites

Versão do OT?

logo4.png

Acesse agora mesmo nosso site e conheca todos os produtos

Site: www.otservhost.com e MSN: [email protected]

Link para o post
Compartilhar em outros sites

entra em data/npc/libs/npcsystem em npchandler e bota

-- Advanced NPC System (Created by Jiddo),

-- Modified by TheForgottenServer Team.

if(NpcHandler == nil) then

local eventSay, eventSayInDefault = {}, 0

-- Constant talkdelay behaviors.

TALKDELAY_NONE = 0 -- No talkdelay. Npc will reply immedeatly.

TALKDELAY_ONTHINK = 1 -- Talkdelay handled through the onThink callback function. (Default)

TALKDELAY_EVENT = 2 -- Not yet implemented

-- Currently applied talkdelay behavior. TALKDELAY_ONTHINK is default.

NPCHANDLER_TALKDELAY = TALKDELAY_ONTHINK

-- Constant conversation behaviors.

CONVERSATION_DEFAULT = 0 -- Conversation through default window, like it was before 8.2 update.

CONVERSATION_PRIVATE = 1 -- Conversation through NPCs chat window, as of 8.2 update. (Default)

--Small Note: Private conversations also means the NPC will use multi-focus system.

-- Currently applied conversation behavior. CONVERSATION_PRIVATE is default.

NPCHANDLER_CONVBEHAVIOR = CONVERSATION_PRIVATE

-- Constant indexes for defining default messages.

MESSAGE_GREET = 1 -- When the player greets the npc.

MESSAGE_FAREWELL = 2 -- When the player unGreets the npc.

MESSAGE_BUY = 3 -- When the npc asks the player if he wants to buy something.

MESSAGE_ONBUY = 4 -- When the player successfully buys something via talk.

MESSAGE_BOUGHT = 5 -- When the player bought something through the shop window.

MESSAGE_SELL = 6 -- When the npc asks the player if he wants to sell something.

MESSAGE_ONSELL = 7 -- When the player successfully sells something via talk.

MESSAGE_SOLD = 8 -- When the player sold something through the shop window.

MESSAGE_MISSINGMONEY = 9 -- When the player does not have enough money.

MESSAGE_NEEDMONEY = 10 -- Same as above, used for shop window.

MESSAGE_MISSINGITEM = 11 -- When the player is trying to sell an item he does not have.

MESSAGE_NEEDITEM = 12 -- Same as above, used for shop window.

MESSAGE_NEEDSPACE = 13 -- When the player don't have any space to buy an item

MESSAGE_NEEDMORESPACE = 14 -- When the player has some space to buy an item, but not enough space

MESSAGE_IDLETIMEOUT = 15 -- When the player has been idle for longer then idleTime allows.

MESSAGE_WALKAWAY = 16 -- When the player walks out of the talkRadius of the npc.

MESSAGE_DECLINE = 17 -- When the player says no to something.

MESSAGE_SENDTRADE = 18 -- When the npc sends the trade window to the player

MESSAGE_NOSHOP = 19 -- When the npc's shop is requested but he doesn't have any

MESSAGE_ONCLOSESHOP = 20 -- When the player closes the npc's shop window

MESSAGE_ALREADYFOCUSED = 21 -- When the player already has the focus of this npc.

MESSAGE_PLACEDINQUEUE = 22 -- When the player has been placed in the costumer queue.

-- Constant indexes for callback functions. These are also used for module callback ids.

CALLBACK_CREATURE_APPEAR = 1

CALLBACK_CREATURE_DISAPPEAR = 2

CALLBACK_CREATURE_SAY = 3

CALLBACK_ONTHINK = 4

CALLBACK_GREET = 5

CALLBACK_FAREWELL = 6

CALLBACK_MESSAGE_DEFAULT = 7

CALLBACK_PLAYER_ENDTRADE = 8

CALLBACK_PLAYER_CLOSECHANNEL = 9

CALLBACK_ONBUY = 10

CALLBACK_ONSELL = 11

-- Addidional module callback ids

CALLBACK_MODULE_INIT = 12

CALLBACK_MODULE_RESET = 13

-- Constant strings defining the keywords to replace in the default messages.

TAG_PLAYERNAME = '|PLAYERNAME|'

TAG_ITEMCOUNT = '|ITEMCOUNT|'

TAG_TOTALCOST = '|TOTALCOST|'

TAG_ITEMNAME = '|ITEMNAME|'

TAG_QUEUESIZE = '|QUEUESIZE|'

NpcHandler = {

keywordHandler = nil,

focuses = nil,

talkStart = nil,

idleTime = 300,

talkRadius = 3,

talkDelayTime = 1, -- Seconds to delay outgoing messages.

queue = nil,

talkDelay = nil,

callbackFunctions = nil,

modules = nil,

shopItems = nil, -- They must be here since ShopModule uses "static" functions

messages = {

-- These are the default replies of all npcs. They can/should be changed individually for each npc.

[MESSAGE_GREET] = 'Welcome, |PLAYERNAME|! I have been expecting you.',

[MESSAGE_FAREWELL] = 'Good bye, |PLAYERNAME|!',

[MESSAGE_BUY] = 'Do you want to buy |ITEMCOUNT| |ITEMNAME| for |TOTALCOST| gold coins?',

[MESSAGE_ONBUY] = 'It was a pleasure doing business with you.',

[MESSAGE_BOUGHT] = 'Bought |ITEMCOUNT|x |ITEMNAME| for |TOTALCOST| gold.',

[MESSAGE_SELL] = 'Do you want to sell |ITEMCOUNT| |ITEMNAME| for |TOTALCOST| gold coins?',

[MESSAGE_ONSELL] = 'Thank you for this |ITEMNAME|, |PLAYERNAME| gold.',

[MESSAGE_SOLD] = 'Sold |ITEMCOUNT|x |ITEMNAME| for |TOTALCOST| gold.',

[MESSAGE_MISSINGMONEY] = 'Sorry, you don\'t have enough money.',

[MESSAGE_NEEDMONEY] = 'You do not have enough money.',

[MESSAGE_MISSINGITEM] = 'You don\'t even have that item, |PLAYERNAME|!',

[MESSAGE_NEEDITEM] = 'You do not have this object.',

[MESSAGE_NEEDSPACE] = 'You do not have enough capacity.',

[MESSAGE_NEEDMORESPACE] = 'You do not have enough capacity for all items.',

[MESSAGE_IDLETIMEOUT] = 'Next, please!',

[MESSAGE_WALKAWAY] = 'How rude!',

[MESSAGE_DECLINE] = 'Not good enough, is it... ?',

[MESSAGE_SENDTRADE] = 'Here\'s my offer, |PLAYERNAME|. Don\'t you like it?',

[MESSAGE_NOSHOP] = 'Sorry, I\'m not offering anything.',

[MESSAGE_ONCLOSESHOP] = 'Thank you, come back when you want something more.',

[MESSAGE_ALREADYFOCUSED]= '|PLAYERNAME|! I am already talking to you...',

[MESSAGE_PLACEDINQUEUE] = '|PLAYERNAME|, please wait for your turn. There are |QUEUESIZE| customers before you.'

}

}

-- Creates a new NpcHandler with an empty callbackFunction stack.

function NpcHandler:new(keywordHandler)

local obj = {}

obj.callbackFunctions = {}

obj.modules = {}

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

obj.focuses = {}

obj.talkStart = {}

else

obj.queue = Queue:new(obj)

obj.focuses = 0

obj.talkStart = 0

end

obj.talkDelay = {}

obj.keywordHandler = keywordHandler

obj.messages = {}

obj.shopItems = {}

setmetatable(obj.messages, self.messages)

self.messages.__index = self.messages

setmetatable(obj, self)

self.__index = self

return obj

end

-- Re-defines the maximum idle time allowed for a player when talking to this npc.

function NpcHandler:setMaxIdleTime(newTime)

self.idleTime = newTime

end

-- Attackes a new keyword handler to this npchandler

function NpcHandler:setKeywordHandler(newHandler)

self.keywordHandler = newHandler

end

-- Function used to change the focus of this npc.

function NpcHandler:addFocus(newFocus)

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

if(self:isFocused(newFocus)) then

return

end

table.insert(self.focuses, newFocus)

else

self.focuses = newFocus

end

self:updateFocus()

end

NpcHandler.changeFocus = NpcHandler.addFocus --"changeFocus" looks better for CONVERSATION_DEFAULT

-- Function used to verify if npc is focused to certain player

function NpcHandler:isFocused(focus)

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

for k,v in pairs(self.focuses) do

if v == focus then

return true

end

end

return false

end

return (self.focuses == focus)

end

-- This function should be called on each onThink and makes sure the npc faces the player it is talking to.

-- Should also be called whenever a new player is focused.

function NpcHandler:updateFocus()

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

for pos, focus in pairs(self.focuses) do

if(focus ~= nil) then

doNpcSetCreatureFocus(focus)

return

end

end

doNpcSetCreatureFocus(0)

else

doNpcSetCreatureFocus(self.focuses)

end

end

-- Used when the npc should un-focus the player.

function NpcHandler:releaseFocus(focus)

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

if(not self:isFocused(focus)) then

return

end

local pos = nil

for k,v in pairs(self.focuses) do

if v == focus then

pos = k

end

end

table.remove(self.focuses, pos)

self.talkStart[focus] = nil

closeShopWindow(focus) --Even if it can not exist, we need to prevent it.

self:updateFocus()

else

closeShopWindow(focus)

self:changeFocus(0)

end

end

-- Returns the callback function with the specified id or nil if no such callback function exists.

function NpcHandler:getCallback(id)

local ret = nil

if(self.callbackFunctions ~= nil) then

ret = self.callbackFunctions[id]

end

return ret

end

-- Changes the callback function for the given id to callback.

function NpcHandler:setCallback(id, callback)

if(self.callbackFunctions ~= nil) then

self.callbackFunctions[id] = callback

end

end

-- Adds a module to this npchandler and inits it.

function NpcHandler:addModule(module)

if(self.modules == nil or module == nil) then

return false

end

module:init(self)

if(module.parseParameters ~= nil) then

module:parseParameters()

end

table.insert(self.modules, module)

return true

end

-- Calls the callback function represented by id for all modules added to this npchandler with the given arguments.

function NpcHandler:processModuleCallback(id, ...)

local ret = true

for i, module in pairs(self.modules) do

local tmpRet = true

if(id == CALLBACK_CREATURE_APPEAR and module.callbackOnCreatureAppear ~= nil) then

tmpRet = module:callbackOnCreatureAppear(unpack(arg))

elseif(id == CALLBACK_CREATURE_DISAPPEAR and module.callbackOnCreatureDisappear ~= nil) then

tmpRet = module:callbackOnCreatureDisappear(unpack(arg))

elseif(id == CALLBACK_CREATURE_SAY and module.callbackOnCreatureSay ~= nil) then

tmpRet = module:callbackOnCreatureSay(unpack(arg))

elseif(id == CALLBACK_PLAYER_ENDTRADE and module.callbackOnPlayerEndTrade ~= nil) then

tmpRet = module:callbackOnPlayerEndTrade(unpack(arg))

elseif(id == CALLBACK_PLAYER_CLOSECHANNEL and module.callbackOnPlayerCloseChannel ~= nil) then

tmpRet = module:callbackOnPlayerCloseChannel(unpack(arg))

elseif(id == CALLBACK_ONBUY and module.callbackOnBuy ~= nil) then

tmpRet = module:callbackOnBuy(unpack(arg))

elseif(id == CALLBACK_ONSELL and module.callbackOnSell ~= nil) then

tmpRet = module:callbackOnSell(unpack(arg))

elseif(id == CALLBACK_ONTHINK and module.callbackOnThink ~= nil) then

tmpRet = module:callbackOnThink(unpack(arg))

elseif(id == CALLBACK_GREET and module.callbackOnGreet ~= nil) then

tmpRet = module:callbackOnGreet(unpack(arg))

elseif(id == CALLBACK_FAREWELL and module.callbackOnFarewell ~= nil) then

tmpRet = module:callbackOnFarewell(unpack(arg))

elseif(id == CALLBACK_MESSAGE_DEFAULT and module.callbackOnMessageDefault ~= nil) then

tmpRet = module:callbackOnMessageDefault(unpack(arg))

elseif(id == CALLBACK_MODULE_RESET and module.callbackOnModuleReset ~= nil) then

tmpRet = module:callbackOnModuleReset(unpack(arg))

end

if(not tmpRet) then

ret = false

break

end

end

return ret

end

-- Returns the message represented by id.

function NpcHandler:getMessage(id)

local ret = nil

if(self.messages ~= nil) then

ret = self.messages[id]

end

return ret

end

-- Changes the default response message with the specified id to newMessage.

function NpcHandler:setMessage(id, newMessage)

if(self.messages ~= nil) then

self.messages[id] = newMessage

end

end

-- Translates all message tags found in msg using parseInfo

function NpcHandler:parseMessage(msg, parseInfo)

local ret = msg

for search, replace in pairs(parseInfo) do

ret = string.gsub(ret, search, replace)

end

return ret

end

-- Makes sure the npc un-focuses the currently focused player

function NpcHandler:unGreet(cid)

if(not self:isFocused(cid)) then

return

end

local callback = self:getCallback(CALLBACK_FAREWELL)

if(callback == nil or callback(cid)) then

if(self:processModuleCallback(CALLBACK_FAREWELL)) then

if(self.queue == nil or not self.queue:greetNext()) then

local msg = self:parseMessage(self:getMessage(MESSAGE_FAREWELL), { [TAG_PLAYERNAME] = getCreatureName(cid) })

self:say(msg, cid, true)

self:releaseFocus(cid)

self:say(msg, cid)

end

end

end

end

-- Greets a new player.

function NpcHandler:greet(cid)

if(cid ~= 0) then

local callback = self:getCallback(CALLBACK_GREET)

if(callback == nil or callback(cid)) then

if(self:processModuleCallback(CALLBACK_GREET, cid)) then

local msg = self:parseMessage(self:getMessage(MESSAGE_GREET), { [TAG_PLAYERNAME] = getCreatureName(cid) })

self:say(msg, cid, true)

self:addFocus(cid)

self:say(msg, cid)

end

end

end

end

-- Handles onCreatureAppear events. If you with to handle this yourself, please use the CALLBACK_CREATURE_APPEAR callback.

function NpcHandler:onCreatureAppear(cid)

local callback = self:getCallback(CALLBACK_CREATURE_APPEAR)

if(callback == nil or callback(cid)) then

if(self:processModuleCallback(CALLBACK_CREATURE_APPEAR, cid)) then

--

end

end

end

-- Handles onCreatureDisappear events. If you with to handle this yourself, please use the CALLBACK_CREATURE_DISAPPEAR callback.

function NpcHandler:onCreatureDisappear(cid)

local callback = self:getCallback(CALLBACK_CREATURE_DISAPPEAR)

if(callback == nil or callback(cid)) then

if(self:processModuleCallback(CALLBACK_CREATURE_DISAPPEAR, cid)) then

if(self:isFocused(cid)) then

self:unGreet(cid)

end

end

end

end

-- Handles onCreatureSay events. If you with to handle this yourself, please use the CALLBACK_CREATURE_SAY callback.

function NpcHandler:onCreatureSay(cid, class, msg)

local callback = self:getCallback(CALLBACK_CREATURE_SAY)

if(callback == nil or callback(cid, class, msg)) then

if(self:processModuleCallback(CALLBACK_CREATURE_SAY, cid, class, msg)) then

if(not self:isInRange(cid)) then

return

end

if(self.keywordHandler ~= nil) then

if((self:isFocused(cid) and (class == TALKTYPE_PRIVATE_PN or NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT)) or not self:isFocused(cid)) then

local ret = self.keywordHandler:processMessage(cid, msg)

if(not ret) then

local callback = self:getCallback(CALLBACK_MESSAGE_DEFAULT)

if(callback ~= nil and callback(cid, class, msg)) then

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

self.talkStart[cid] = os.time()

else

self.talkStart = os.time()

end

end

else

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

self.talkStart[cid] = os.time()

else

self.talkStart = os.time()

end

end

end

end

end

end

end

-- Handles onPlayerEndTrade events. If you wish to handle this yourself, use the CALLBACK_PLAYER_ENDTRADE callback.

function NpcHandler:onPlayerEndTrade(cid)

local callback = self:getCallback(CALLBACK_PLAYER_ENDTRADE)

if(callback == nil or callback(cid)) then

if(self:processModuleCallback(CALLBACK_PLAYER_ENDTRADE, cid, class, msg)) then

if(self:isFocused(cid)) then

local parseInfo = { [TAG_PLAYERNAME] = getPlayerName(cid) }

local msg = self:parseMessage(self:getMessage(MESSAGE_ONCLOSESHOP), parseInfo)

self:say(msg, cid)

end

end

end

end

-- Handles onPlayerCloseChannel events. If you wish to handle this yourself, use the CALLBACK_PLAYER_CLOSECHANNEL callback.

function NpcHandler:onPlayerCloseChannel(cid)

local callback = self:getCallback(CALLBACK_PLAYER_CLOSECHANNEL)

if(callback == nil or callback(cid)) then

if(self:processModuleCallback(CALLBACK_PLAYER_CLOSECHANNEL, cid, class, msg)) then

if(self:isFocused(cid)) then

self:unGreet(cid)

end

end

end

end

-- Handles onBuy events. If you wish to handle this yourself, use the CALLBACK_ONBUY callback.

function NpcHandler:onBuy(cid, itemid, subType, amount, ignoreCap, inBackpacks)

local callback = self:getCallback(CALLBACK_ONBUY)

if(callback == nil or callback(cid, itemid, subType, amount, ignoreCap, inBackpacks)) then

if(self:processModuleCallback(CALLBACK_ONBUY, cid, itemid, subType, amount, ignoreCap, inBackpacks)) then

--

end

end

end

-- Handles onSell events. If you wish to handle this yourself, use the CALLBACK_ONSELL callback.

function NpcHandler:onSell(cid, itemid, subType, amount, ignoreCap, inBackpacks)

local callback = self:getCallback(CALLBACK_ONSELL)

if(callback == nil or callback(cid, itemid, subType, amount, ignoreCap, inBackpacks)) then

if(self:processModuleCallback(CALLBACK_ONSELL, cid, itemid, subType, amount, ignoreCap, inBackpacks)) then

--

end

end

end

-- Handles onThink events. If you wish to handle this yourself, please use the CALLBACK_ONTHINK callback.

function NpcHandler:onThink()

local callback = self:getCallback(CALLBACK_ONTHINK)

if(callback == nil or callback()) then

if(NPCHANDLER_TALKDELAY == TALKDELAY_ONTHINK) then

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

for cid, talkDelay in pairs(self.talkDelay) do

if(talkDelay.time ~= nil and talkDelay.message ~= nil and os.time() >= talkDelay.time) then

selfSay(talkDelay.message, cid)

self.talkDelay[cid] = nil

end

end

elseif(self.talkDelay.time ~= nil and self.talkDelay.message ~= nil and os.time() >= self.talkDelay.time) then

selfSay(self.talkDelay.message)

self.talkDelay.time = nil

self.talkDelay.message = nil

end

end

if(self:processModuleCallback(CALLBACK_ONTHINK)) then

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

for pos, focus in pairs(self.focuses) do

if(focus ~= nil) then

if(not self:isInRange(focus)) then

self:onWalkAway(focus)

elseif((os.time() - self.talkStart[focus]) > self.idleTime) then

self:unGreet(focus)

else

self:updateFocus()

end

end

end

elseif(self.focuses ~= 0) then

if(not self:isInRange(self.focuses)) then

self:onWalkAway(self.focuses)

elseif(os.time()-self.talkStart > self.idleTime) then

self:unGreet(self.focuses)

else

self:updateFocus()

end

end

end

end

end

-- Tries to greet the player with the given cid.

function NpcHandler:onGreet(cid)

if(self:isInRange(cid)) then

if(NPCHANDLER_CONVBEHAVIOR == CONVERSATION_PRIVATE) then

if(not self:isFocused(cid)) then

self:greet(cid)

return

end

elseif(NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT) then

if(self.focuses == 0) then

self:greet(cid)

elseif(self.focuses == cid) then

local msg = self:getMessage(MESSAGE_ALREADYFOCUSED)

local parseInfo = { [TAG_PLAYERNAME] = getCreatureName(cid) }

msg = self:parseMessage(msg, parseInfo)

self:say(msg)

else

if(not self.queue:isInQueue(cid)) then

self.queue:push(cid)

end

local msg = self:getMessage(MESSAGE_PLACEDINQUEUE)

local parseInfo = { [TAG_PLAYERNAME] = getCreatureName(cid), [TAG_QUEUESIZE] = self.queue:getSize() }

msg = self:parseMessage(msg, parseInfo)

self:say(msg)

end

end

end

end

-- Simply calls the underlying unGreet function.

function NpcHandler:onFarewell(cid)

self:unGreet(cid)

end

-- Should be called on this npc's focus if the distance to focus is greater then talkRadius.

function NpcHandler:onWalkAway(cid)

if(self:isFocused(cid)) then

local callback = self:getCallback(CALLBACK_CREATURE_DISAPPEAR)

if(callback == nil or callback(cid)) then

if(self:processModuleCallback(CALLBACK_CREATURE_DISAPPEAR, cid)) then

if(self.queue == nil or not self.queue:greetNext()) then

self:releaseFocus(cid)

self:say(self:parseMessage(self:getMessage(MESSAGE_WALKAWAY), { [TAG_PLAYERNAME] = getPlayerName(cid) }))

end

end

end

end

end

-- Returns true if cid is within the talkRadius of this npc.

function NpcHandler:isInRange(cid)

local distance = getDistanceTo(cid) or -1

if(distance == -1) then

return false

end

return (distance <= self.talkRadius)

end

-- Resets the npc into it's initial state (in regard of the keyrodhandler).

-- All modules are also receiving a reset call through their callbackOnModuleReset function.

function NpcHandler:resetNpc()

if(self:processModuleCallback(CALLBACK_MODULE_RESET)) then

self.keywordHandler:reset()

end

end

-- Makes the npc represented by this instance of NpcHandler say something.

-- This implements the currently set type of talkdelay.

-- shallDelay is a boolean value. If it is false, the message is not delayed. Default value is false.

_say = function(message, focus, publicize, shallDelay, delay)

if not focus then

stopEvent(eventSayInDefault)

eventSayInDefault = addEvent(function(z) doCreatureSay(z[1], z[2], TALKTYPE_SAY) end, NpcHandler.talkDelayTime * 1000, {getNpcCid(), message})

return

elseif type(message) == "table" then

return doNPCTalkALot(message, delay or 10000, focus)

elseif eventDelayedSay[focus] then

cancelNPCTalk(eventDelayedSay[focus])

end

local shallDelay = not shallDelay and true or shallDelay

if(NPCHANDLER_TALKDELAY == TALKDELAY_NONE or not shallDelay) then

if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then

selfSay(message, focus, publicize and TRUE or FALSE)

return

else

selfSay(message)

return

end

end

if NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT then

stopEvent(eventSay[focus])

eventSay[focus] = addEvent(function(x) if isPlayer(x[3]) == TRUE then doCreatureSay(x[1], x[2], TALKTYPE_PRIVATE_NP, false, x[3], getCreaturePosition(x[1])) end end, NpcHandler.talkDelayTime * 1000, {getNpcCid(), message, focus})

if(publicize) then

addEvent(function(y) local spectators = getSpectators(getCreaturePosition(y[1]), 7, 5, false) for i = 1, #spectators do if spectators == y[3] then table.remove(spectators, i) break end end if #spectators > 0 then for i, tid in ipairs(spectators) do if(isPlayer(tid) == TRUE) then doCreatureSay(y[1], y[2], TALKTYPE_SAY, false, tid, getCreaturePosition(getNpcCid())) end end end end, NpcHandler.talkDelayTime * 1000, {getNpcCid(), message, focus})

end

else

addEvent(function(x) doCreatureSay(x[1], x[2], TALKTYPE_SAY) end, NpcHandler.talkDelayTime * 1000, {getNpcCid(), message})

end

end

function NpcHandler:say(message, focus, publicize, shallDelay, delay)

_say(message, focus, publicize, shallDelay, delay)

end

_selfSay = selfSay

selfSay = _say

end

logo4.png

Acesse agora mesmo nosso site e conheca todos os produtos

Site: www.otservhost.com e MSN: [email protected]

Link para o post
Compartilhar em outros sites
  • 1 month later...
  • 8 months later...

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emojis são permitidos.

×   Seu link foi automaticamente incorporado.   Mostrar como link

×   Seu conteúdo anterior foi restaurado.   Limpar o editor

×   Não é possível colar imagens diretamente. Carregar ou inserir imagens do URL.

  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.


  • Conteúdo Similar

    • Por ambrozii0
      Gostaria de fazer um pedido de um NPC de Task progressiva,

      Ele iniciaria dando missões para level 8 para caçar Troll, Rotworm e Ghoul.
       
      No level 30 liberaria: Cyclops, Dragon e Wyrm... e assim em diante se puder deixar comentado eu faço as criaturas na sequencia dos leveis seguintes.
       
      O jogador pode fazer as tasks dos leveis anteriores mesmo que já tenha ultrapassado o level do próximo nível de task.
       
      E o jogador ao terminar a missão poderia escolher a recompensa em gold ou experiência. As tasks podem se repetir sem problema, mas apenas pode pegar uma de cada vez.
       
      Ao finalizar todas as tasks o jogador ganha uma montaria.
       
      Minha versão de cliente é 12.91
      Versão da Canary 2.6.1
      Não sei qual o TFS do meu servidor.
    • Por ILex WilL
      Olá, Alguém poderia me ajudar com uns Scripts? nem que seja cobrando, dependendo eu pago para me ajudar...
    • Por Kill of sumoners
      Boa noite, estou com um erro ao atacar um player em meu sv eu nao pego pk, nem sai magia, aparece a mensagem "voce so pode usar isso em criaturas"
      obs: magia em area acerta e pega pk, apenas as targets ou hits de arma nao vao 
    • Por daviscript
      Após verificar que vários servidores estão sofrendo com problemas na página Guilds, onde era possível fazer diversas modificações com os players de qualquer guild, até a Cipsoft passou por esse problema recentemente...
      Resolvi compartilhar com vocês a correção de todos os Bugs conhecidos na Página de Guilds.
       
      Foram fixados os seguintes Bugs:
      ● Remover Players que não forem de sua guild.
      ● Aceitar guild com 1 personagem que não seja da sua conta.
      ● Editar o Text/Title de 1 player que não esteja na sua guild.
      ● Editar Ranks que não sejam da sua guild.
      ● Editar Rank de Players que não são da sua guild.
       
      Qualquer outro BUG que você encontrar... Pode listar aqui nesse tópico.
       
      OBS: É meu primeiro post... Então se estiver no local errado ou se algum moderador quiser reformular / formatar o tópico, fique a vontade.
       
       Vou deixar o Spoiler do php abaixo, mas também estou anexando o arquivo.
       
       
      Download: Mediafire
      Scan: Virus Total
       
       
    • Por Jpminatel
      Estou com os seguintes erros ; e procuro quem poça ajudar ai a eliminar esses 3 erros , erro 1 e 2 acontece qnd um pokemon usa ps   e o erro 3 é nas potions 
      [Error - TalkAction Interface] 
      [30/01/2022 17:04:25] data/talkactions/scripts/move1.lua:onSay
      [30/01/2022 17:04:25] Description: 
      [30/01/2022 17:04:25] data/lib/some functions.lua:338: attempt to call global 'hasTile' (a nil value)
      [30/01/2022 17:04:25] stack traceback:
      [30/01/2022 17:04:25]     data/lib/some functions.lua:338: in function 'getThingFromPosWithProtect'
      Erro 2 ;
      [30/01/2022 18:08:53] [Error - Spell Interface] 
      [30/01/2022 18:08:53] In a timer event called from: 
      [30/01/2022 18:08:53] data/spells/scripts/ps/Earthquake.lua:onCastSpell
      [30/01/2022 18:08:53] Description: 
      [30/01/2022 18:08:53] data/lib/some functions.lua:338: attempt to call global 'hasTile' (a nil value)
      [30/01/2022 18:08:53] stack traceback:
      [30/01/2022 18:08:53]     data/lib/some functions.lua:338: in function 'getThingFromPosWithProtect'
      [30/01/2022 18:08:53]     data/lib/newStatusSyst.lua:844: in function 'doMoveInArea2'
      [30/01/2022 18:08:53]     data/lib/pokemon moves.lua:1355: in function <data/lib/pokemon moves.lua:1351>
      [30/01/2022 18:08:54] [Error - Spell Interface] 
      [30/01/2022 18:08:54] In a timer event called from: 
      [30/01/2022 18:08:54] data/spells/scripts/ps/Earthquake.lua:onCastSpell
      [30/01/2022 18:08:54] Description: 
      [30/01/2022 18:08:54] data/lib/some functions.lua:338: attempt to call global 'hasTile' (a nil value)
      [30/01/2022 18:08:54] stack traceback:
      [30/01/2022 18:08:54]     data/lib/some functions.lua:338: in function 'getThingFromPosWithProtect'
      [30/01/2022 18:08:54]     data/lib/newStatusSyst.lua:844: in function 'doMoveInArea2'
      [30/01/2022 18:08:54]     data/lib/pokemon moves.lua:1355: in function <data/lib/pokemon moves.lua:1351>
      [30/01/2022 18:18:20] [Error - TalkAction Interface] 
      [30/01/2022 18:18:20] data/talkactions/scripts/move1.lua:onSay
      [30/01/2022 18:18:20] Description: 
      [30/01/2022 18:18:20] data/lib/some functions.lua:338: attempt to call global 'hasTile' (a nil value)
      [30/01/2022 18:18:20] stack traceback:
      [30/01/2022 18:18:20]     data/lib/some functions.lua:338: in function 'getThingFromPosWithProtect'
      [30/01/2022 18:18:20]     data/lib/newStatusSyst.lua:1119: in function 'doMoveInAreaMulti'
      [30/01/2022 18:18:20]     data/lib/pokemon moves.lua:458: in function 'docastspell'
      [30/01/2022 18:18:20]     data/talkactions/scripts/move1.lua:173: in function <data/talkactions/scripts/move1.lua:20>
      Erro 3 ; 
      erro potion 
      [30/01/2022 18:48:35] [Error - Action Interface] 
      [30/01/2022 18:48:35] data/actions/scripts/potion.lua:onUse
      [30/01/2022 18:48:35] Description: 
      [30/01/2022 18:48:35] data/lib/some functions.lua:338: attempt to call global 'hasTile' (a nil value)
      [30/01/2022 18:48:35] stack traceback:
      [30/01/2022 18:48:35]     data/lib/some functions.lua:338: in function 'getThingFromPosWithProtect'
      [30/01/2022 18:48:35]     data/actions/scripts/potion.lua:45: in function <data/actions/scripts/potion.lua:43>
      [30/01/2022 18:48:39] [Error - Action Interface] 
      [30/01/2022 18:48:39] data/actions/scripts/potion.lua:onUse
      [30/01/2022 18:48:39] Description: 
      [30/01/2022 18:48:39] data/lib/some functions.lua:338: attempt to call global 'hasTile' (a nil value)
      [30/01/2022 18:48:39] stack traceback:
      [30/01/2022 18:48:39]     data/lib/some functions.lua:338: in function 'getThingFromPosWithProtect'
      [30/01/2022 18:48:39]     data/actions/scripts/potion.lua:45: in function <data/actions/scripts/potion.lua:43>
       
×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo