OTHispano
¿Quieres reaccionar a este mensaje? Regístrate en el foro con unos pocos clics o inicia sesión para continuar.

Ir abajo
God Assassin
God Assassin
Miembro
Mensajes Mensajes : 21

npc y runas ayuda Empty npc y runas ayuda

Vie Jun 01, 2012 12:45 pm
hola othispano tengo un problema es con los npc les digo hi y no contestan nesesito ayuda y tambien quisiera saber como hacer infito las runas y las posiones espero y puedan aydarme uso otx ayudenme porfavor


Última edición por God Assassin el Vie Jun 01, 2012 5:05 pm, editado 1 vez
Falcon
Falcon
Administrador
Mensajes Mensajes : 350
http://www.othispano.net

npc y runas ayuda Empty Re: npc y runas ayuda

Vie Jun 01, 2012 12:52 pm
Ves a tu carpeta NPC/Libs/
Y en npc.lua

Pon esto:
Código:
function selfSayChannel(cid, message)
   return selfSay(message, cid, false)
end

function selfMoveToThing(id)
   errors(false)
   local thing = getThing(id)

   errors(true)
   if(thing.uid == 0) then
      return
   end

   local t = getThingPosition(id)
   selfMoveTo(t.x, t.y, t.z)
   return
end

function selfMoveTo(x, y, z)
   local position = {x = 0, y = 0, z = 0}
   if(type(x) ~= "table") then
      position = Position(x, y, z)
   else
      position = x
   end

   if(isValidPosition(position)) then
      doSteerCreature(getNpcId(), position)
   end
end

function selfMove(direction, flags)
   local flags = flags or 0
   doMoveCreature(getNpcId(), direction, flags)
end

function selfTurn(direction)
   doCreatureSetLookDirection(getNpcId(), direction)
end

function getNpcDistanceTo(id)
   errors(false)
   local thing = getThing(id)

   errors(true)
   if(thing.uid == 0) then
      return nil
   end

   local c = getCreaturePosition(id)
   if(not isValidPosition(c)) then
      return nil
   end

   local s = getCreaturePosition(getNpcId())
   if(not isValidPosition(s) or s.z ~= c.z) then
      return nil
   end

   return math.max(math.abs(s.x - c.x), math.abs(s.y - c.y))
end

function doMessageCheck(message, keyword)
   if(type(keyword) == "table") then
      return table.isStrIn(keyword, message)
   end

   local a, b = message:lower(), keyword:lower()
   if(keyword == message) then
      return true
   end

   return message:find(keyword) and not message:find('(%w+)' .. keyword)
end

function doNpcSellItem(cid, itemid, amount, subType, ignoreCap, inBackpacks, backpack)
   local amount, subType, ignoreCap, item = amount or 1, subType or 1, ignoreCap and true or false, 0
   if(isItemStackable(itemid)) then
      if(isItemRune(itemid)) then
         amount = amount * subType
      end

      local count = amount
      repeat
         item = doCreateItemEx(itemid, math.min(100, count))
         if(doPlayerAddItemEx(cid, item, ignoreCap) ~= RETURNVALUE_NOERROR) then
            return 0, 0
         end

         count = count - math.min(100, count)
      until count == 0
      return amount, 0
   end

   local a = 0
   if(inBackpacks) then
      local container, b = doCreateItemEx(backpack, 1), 1
      for i = 1, amount do
         item = doAddContainerItem(container, itemid, subType)
         if(itemid == ITEM_PARCEL) then
            doAddContainerItem(item, ITEM_LABEL)
         end

         if(isInArray({(getContainerCapById(backpack) * b), amount}, i)) then
            if(doPlayerAddItemEx(cid, container, ignoreCap) ~= RETURNVALUE_NOERROR) then
               b = b - 1
               break
            end

            a = i
            if(amount > i) then
               container = doCreateItemEx(backpack, 1)
               b = b + 1
            end
         end
      end

      return a, b
   end

   for i = 1, amount do
      item = doCreateItemEx(itemid, subType)
      if(itemid == ITEM_PARCEL) then
         doAddContainerItem(item, ITEM_LABEL)
      end

      if(doPlayerAddItemEx(cid, item, ignoreCap) ~= RETURNVALUE_NOERROR) then
         break
      end

      a = i
   end

   return a, 0
end

function doRemoveItemIdFromPosition(id, n, position)
   local thing = getThingFromPos({x = position.x, y = position.y, z = position.z, stackpos = 1})
   if(thing.itemid ~= id) then
      return false
   end

   doRemoveItem(thing.uid, n)
   return true
end

function getNpcName()
   return getCreatureName(getNpcId())
end

function getNpcPos()
   return getThingPosition(getNpcId())
end

function selfGetPosition()
   local t = getThingPosition(getNpcId())
   return t.x, t.y, t.z
end

msgcontains = doMessageCheck
moveToPosition = selfMoveTo
moveToCreature = selfMoveToThing
selfMoveToCreature = selfMoveToThing
selfMoveToPosition = selfMoveTo
isPlayerPremiumCallback = isPremium
doPosRemoveItem = doRemoveItemIdFromPosition
doRemoveItemIdFromPos = doRemoveItemIdFromPosition
doNpcBuyItem = doPlayerRemoveItem
doNpcSetCreatureFocus = selfFocus
getNpcCid = getNpcId
getDistanceTo = getNpcDistanceTo
getDistanceToCreature = getNpcDistanceTo
getNpcDistanceToCreature = getNpcDistanceTo

Ahora, en npcsystem, cambia keywordhandler, por esto;
Código:
-- Advanced NPC System (Created by Jiddo),
-- Modified by TheForgottenServer Team,
-- Modified by Silver Moonlight Team.

if(KeywordHandler == nil) then
   BEHAVIOR_SIMPLE = 1 -- Does not support nested keywords. If you choose this setting you must use a variable such as 'talkState' to keep track of how to handle keywords.
   BEHAVIOR_NORMAL = 2 -- Default behvaior. If a sub-keyword is not found, then the root is searched, not the parent hierarchy,
   BEHAVIOR_NORMAL_EXTENDED = 3 -- Same as BEHAVIOR_NORMAL but it also searches through the last node's parent.
   BEHAVIOR_COMPLEX = 4 -- Extended behavior. It a sub-keyword is not found, then the entire keyword hierarchy is searched upwards until root is reached.

   -- BEHAVIOR_NORMAL_EXTENDED is recommended as it (probably) mimics the behavior of real Tibia's NPCs the most.
   --      However, you are strongly recommended to test some (or all) other settings as well as it might suit you better.
   --      Also note that not much difference can be seen with the different settings unless you have a npc with a quite heavy
   --      nestled keyword hierarchy.
   -- Note: BEHAVIOR_SIMPLE should not be used unless you have any special reason to do so as it forces you to keep track of talkStates etc.
   --      This was pretty much the method used in the 2.0x versions of this system. It is here mainly for compability issues.
   KEYWORD_BEHAVIOR = BEHAVIOR_NORMAL_EXTENDED

   KeywordNode = {
      keywords = nil,
      callback = nil,
      parameters = nil,
      children = nil,
      parent = nil
   }

   -- Created a new keywordnode with the given keywords, callback function and parameters and without any childNodes.
   function KeywordNode:new(keys, func, param)
      local obj = {}
      obj.keywords = keys
      obj.callback = func
      obj.parameters = param
      obj.children = {}
      setmetatable(obj, self)
      self.__index = self
      return obj
   end

   -- Calls the underlying callback function if it is not nil.
   function KeywordNode:processMessage(cid, message)
      return (self.callback == nil or self.callback(cid, message, self.keywords, self.parameters, self))
   end

   -- Returns true if message contains all patterns/strings found in keywords.
   function KeywordNode:checkMessage(message)
      local ret = true
      if(self.keywords.callback ~= nil) then
         return self.keywords.callback(self.keywords, message)
      end
      for i,v in ipairs(self.keywords) do
         if(type(v) == 'string') then
            local a, b = string.find(message, v)
            if(a == nil or b == nil) then
               ret = false
               break
            end
         end
      end
      return ret
   end

   -- Returns the parent of this node or nil if no such node exists.
   function KeywordNode:getParent()
      return self.parent
   end

   -- Returns an array of the callback function parameters assosiated with this node.
   function KeywordNode:getParameters()
      return self.parameters
   end

   -- Returns an array of the triggering keywords assosiated with this node.
   function KeywordNode:getKeywords()
      return self.keywords
   end

   -- Adds a childNode to this node. Creates the childNode based on the parameters (k = keywords, c = callback, p = parameters)
   function KeywordNode:addChildKeyword(keywords, callback, parameters)
      local new = KeywordNode:new(keywords, callback, parameters)
      return self:addChildKeywordNode(new)
   end

   -- Adds a pre-created childNode to this node. Should be used for example if several nodes should have a common child.
   function KeywordNode:addChildKeywordNode(childNode)
      table.insert(self.children, childNode)
      childNode.parent = self
      return childNode
   end

   KeywordHandler = {
      root = nil,
      lastNode = nil
   }

   -- Creates a new keywordhandler with an empty rootnode.
   function KeywordHandler:new()
      local obj = {}
      obj.root = KeywordNode:new(nil, nil, nil)
      setmetatable(obj, self)
      self.__index = self
      return obj
   end

   -- Resets the lastNode field, and this resetting the current position in the node hierarchy to root.
   function KeywordHandler:reset()
      self.lastNode = nil
   end

   -- Makes sure the correct childNode of lastNode gets a chance to process the message.
   --   The behavior of this function depends much on the KEYWORD_BEHAVIOR.
   function KeywordHandler:processMessage(cid, message)
      local node = self:getLastNode()
      if(node == nil) then
         error('No root node found.')
         return false
      end
      if(KEYWORD_BEHAVIOR == BEHAVIOR_SIMPLE) then
         local ret = self:processNodeMessage(node, cid, message)
         if(ret) then
            return true
         end
      elseif(KEYWORD_BEHAVIOR == BEHAVIOR_NORMAL or KEYWORD_BEHAVIOR == BEHAVIOR_NORMAL_EXTENDED) then
         local ret = self:processNodeMessage(node, cid, message)
         if(ret) then
            return true
         end
         if(KEYWORD_BEHAVIOR == BEHAVIOR_NORMAL_EXTENDED and node:getParent()) then
            node = node:getParent() -- Search through the parent.
            local ret = self:processNodeMessage(node, cid, message)
            if(ret) then
               return true
            end
         end
         if(node ~= self:getRoot()) then
            node = self:getRoot() -- Search through the root.
            local ret = self:processNodeMessage(node, cid, message)
            if(ret) then
               return true
            end
         end
      elseif(KEYWORD_BEHAVIOR == BEHAVIOR_COMPLEX) then
         while true do
            local ret = self:processNodeMessage(node, cid, message)
            if(ret) then
               return true
            end

            if(node:getParent() ~= nil) then
               node = node:getParent() -- Move one step upwards in the hierarchy.
            else
               break
            end
         end
      else
         error('Unknown keyword behavior.')
      end
      return false
   end

   -- Tries to process the given message using the node parameter's children and calls the node's callback function if found.
   --   Returns the childNode which processed the message or nil if no such node was found.
   function KeywordHandler:processNodeMessage(node, cid, message)
      local messageLower = string.lower(message)
      for i, childNode in pairs(node.children) do
         if(childNode:checkMessage(messageLower)) then
            local oldLast = self.lastNode
            self.lastNode = childNode
            childNode.parent = node -- Make sure node is the parent of childNode (as one node can be parent to several nodes).
            if(childNode:processMessage(cid, message)) then
               return true
            else
               self.lastNode = oldLast
            end
         end
      end
      return false
   end

   -- Returns the root keywordnode
   function KeywordHandler:getRoot()
      return self.root
   end

   -- Returns the last processed keywordnode or root if no last node is found.
   function KeywordHandler:getLastNode()
      if(KEYWORD_BEHAVIOR == BEHAVIOR_SIMPLE) then
         return self:getRoot()
      else
         return self.lastNode or self:getRoot()
      end
   end

   -- Adds a new keyword to the root keywordnode. Returns the new node.
   function KeywordHandler:addKeyword(keys, callback, parameters)
      return self:getRoot():addChildKeyword(keys, callback, parameters)
   end

   -- Moves the current position in the keyword hierarchy count steps upwards. Count defalut value = 1.
   --   This function MIGHT not work properly yet. Use at your own risk.
   function KeywordHandler:moveUp(count)
      local steps = count
      if(steps == nil) then
         steps = 1
      end
      for i = 1, steps,1 do
         if(self.lastNode == nil) then
            break
         else
            self.lastNode = self.lastNode:getParent() or self:getRoot()
         end
      end
      return self.lastNode
   end
end

main.lua por esto:
Código:
-- Advanced NPC System (Created by Jiddo),
-- Modified by TheForgottenServer Team,
-- Modified by Silver Moonlight Team

if(NpcSystem == nil) then
   -- Loads the underlying classes of the npcsystem.
   dofile(getDataDir() .. 'npc/lib/npcsystem/keywordhandler.lua')
   dofile(getDataDir() .. 'npc/lib/npcsystem/queue.lua')
   dofile(getDataDir() .. 'npc/lib/npcsystem/npchandler.lua')
   dofile(getDataDir() .. 'npc/lib/npcsystem/modules.lua')

   -- Global npc constants:

   -- Keyword nestling behavior. For more information look at the top of keywordhandler.lua
   KEYWORD_BEHAVIOR = BEHAVIOR_NORMAL_EXTENDED

   -- Greeting and unGreeting keywords. For more information look at the top of modules.lua
   FOCUS_GREETWORDS = {'hi', 'hello', 'hey'}
   FOCUS_FAREWELLWORDS = {'bye', 'farewell', 'cya'}

   -- The word for requesting trade window. For more information look at the top of modules.lua
   SHOP_TRADEREQUEST = {'offer', 'trade'}

   -- The word for accepting/declining an offer. CAN ONLY CONTAIN ONE FIELD! For more information look at the top of modules.lua
   SHOP_YESWORD = {'yes'}
   SHOP_NOWORD = {'no'}

   -- Pattern used to get the amount of an item a player wants to buy/sell.
   PATTERN_COUNT = '%d+'

   -- Talkdelay behavior. For more information, look at the top of npchandler.lua.
   NPCHANDLER_TALKDELAY = TALKDELAY_ONTHINK

   -- Conversation behavior. For more information, look at the top of npchandler.lua.
   NPCHANDLER_CONVBEHAVIOR = CONVERSATION_PRIVATE

   -- Constant strings defining the keywords to replace in the default messages.
   --   For more information, look at the top of npchandler.lua...
   TAG_PLAYERNAME = '|PLAYERNAME|'
   TAG_ITEMCOUNT = '|ITEMCOUNT|'
   TAG_TOTALCOST = '|TOTALCOST|'
   TAG_ITEMNAME = '|ITEMNAME|'
   TAG_QUEUESIZE = '|QUEUESIZE|'

   NpcSystem = {}

   -- Gets an npcparameter with the specified key. Returns nil if no such parameter is found.
   function NpcSystem.getParameter(key)
      local ret = getNpcParameter(tostring(key))
      if((type(ret) == 'number' and ret == 0) or ret == nil) then
         return nil
      else
         return ret
      end
   end

   -- Parses all known parameters for the npc. Also parses parseable modules.
   function NpcSystem.parseParameters(npcHandler)
      local ret = NpcSystem.getParameter('idletime')
      if(ret ~= nil) then
         npcHandler.idleTime = tonumber(ret)
      end
      local ret = NpcSystem.getParameter('talkradius')
      if(ret ~= nil) then
         npcHandler.talkRadius = tonumber(ret)
      end
      local ret = NpcSystem.getParameter('message_greet')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_GREET, ret)
      end
      local ret = NpcSystem.getParameter('message_farewell')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_FAREWELL, ret)
      end
      local ret = NpcSystem.getParameter('message_decline')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_DECLINE, ret)
      end
      local ret = NpcSystem.getParameter('message_needmorespace')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_NEEDMORESPACE, ret)
      end
      local ret = NpcSystem.getParameter('message_needspace')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_NEEDSPACE, ret)
      end
      local ret = NpcSystem.getParameter('message_sendtrade')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_SENDTRADE, ret)
      end
      local ret = NpcSystem.getParameter('message_noshop')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_NOSHOP, ret)
      end
      local ret = NpcSystem.getParameter('message_oncloseshop')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_ONCLOSESHOP, ret)
      end
      local ret = NpcSystem.getParameter('message_onbuy')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_ONBUY, ret)
      end
      local ret = NpcSystem.getParameter('message_onsell')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_ONSELL, ret)
      end
      local ret = NpcSystem.getParameter('message_missingmoney')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_MISSINGMONEY, ret)
      end
      local ret = NpcSystem.getParameter('message_needmoney')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_NEEDMONEY, ret)
      end
      local ret = NpcSystem.getParameter('message_missingitem')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_MISSINGITEM, ret)
      end
      local ret = NpcSystem.getParameter('message_needitem')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_NEEDITEM, ret)
      end
      local ret = NpcSystem.getParameter('message_idletimeout')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_IDLETIMEOUT, ret)
      end
      local ret = NpcSystem.getParameter('message_walkaway')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_WALKAWAY, ret)
      end
      local ret = NpcSystem.getParameter('message_alreadyfocused')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_ALREADYFOCUSED, ret)
      end
      local ret = NpcSystem.getParameter('message_placedinqueue')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_PLACEDINQUEUE, ret)
      end
      local ret = NpcSystem.getParameter('message_buy')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_BUY, ret)
      end
      local ret = NpcSystem.getParameter('message_sell')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_SELL, ret)
      end
      local ret = NpcSystem.getParameter('message_bought')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_BOUGHT, ret)
      end
      local ret = NpcSystem.getParameter('message_sold')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_SOLD, ret)
      end

      -- Parse modules.
      for parameter, module in pairs(Modules.parseableModules) do
         local ret = NpcSystem.getParameter(parameter)
         if(ret ~= nil) then
            local number = tonumber(ret)
            if(number ~= nil and number ~= 0) then
               npcHandler:addModule(module:new())
            end
         end
      end
   end
end

npchander, por esto:
Código:
-- Advanced NPC System (Created by Jiddo),
-- Modified by TheForgottenServer Team,
-- Modified by Silver Moonlight Team.

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 = 300,
      talkRadius = 3,
      talkDelayTime = 400, -- 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(not isCreature(newFocus)) then
         return
      end

      if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
         if(self:isFocused(newFocus, true)) then
            return
         end

         table.insert(self.focuses, newFocus)
      else
         self.focuses = newFocus
      end

      self:updateFocus(true)
   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, creatureCheck)
      local creatureCheck = creatureCheck or false
      if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
         for k, v in pairs(self.focuses) do
            if(v == focus) then
               if(creatureCheck or isCreature(v)) then
                  return true
               end

               self:unsetFocus(focus, k)
               return false
            end
         end

         return false
      end

      if(creatureCheck or isCreature(self.focuses)) then
         return self.focuses == focus
      end

      self:changeFocus(0)
      return false
   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(creatureCheck)
      local creatureCheck = creatureCheck or false
      if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
         for _, focus in pairs(self.focuses) do
            if(creatureCheck or isCreature(focus)) then
               doNpcSetCreatureFocus(focus)
               return
            end
         end
      elseif(creatureCheck or isCreature(self.focuses)) then
         doNpcSetCreatureFocus(self.focuses)
         return
      end

      doNpcSetCreatureFocus(0)
   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

         if(pos ~= nil) then
            closeShopWindow(focus)
            self:unsetFocus(focus, pos)
         end
      elseif(self.focuses == focus) then
         if(isCreature(focus)) then
            closeShopWindow(focus)
         end

         self:changeFocus(0)
      end
   end

   -- Internal un-focusing function, beware using!
   function NpcHandler:unsetFocus(focus, pos)
      if(type(self.focuses) ~= "table" or pos == nil or self.focuses[pos] == nil) then
         return
      end

      table.remove(self.focuses, pos)
      self.talkStart[focus] = nil
      self:updateFocus()
   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 _, module in pairs(self.modules) do
         local tmpRet = true
         if(id == CALLBACK_CREATURE_APPEAR and module.callbackOnCreatureAppear ~= nil) then
            tmpRet = module:callbackOnCreatureAppear(...)
         elseif(id == CALLBACK_CREATURE_DISAPPEAR and module.callbackOnCreatureDisappear ~= nil) then
            tmpRet = module:callbackOnCreatureDisappear(...)
         elseif(id == CALLBACK_CREATURE_SAY and module.callbackOnCreatureSay ~= nil) then
            tmpRet = module:callbackOnCreatureSay(...)
         elseif(id == CALLBACK_PLAYER_ENDTRADE and module.callbackOnPlayerEndTrade ~= nil) then
            tmpRet = module:callbackOnPlayerEndTrade(...)
         elseif(id == CALLBACK_PLAYER_CLOSECHANNEL and module.callbackOnPlayerCloseChannel ~= nil) then
            tmpRet = module:callbackOnPlayerCloseChannel(...)
         elseif(id == CALLBACK_ONBUY and module.callbackOnBuy ~= nil) then
            tmpRet = module:callbackOnBuy(...)
         elseif(id == CALLBACK_ONSELL and module.callbackOnSell ~= nil) then
            tmpRet = module:callbackOnSell(...)
         elseif(id == CALLBACK_ONTHINK and module.callbackOnThink ~= nil) then
            tmpRet = module:callbackOnThink(...)
         elseif(id == CALLBACK_GREET and module.callbackOnGreet ~= nil) then
            tmpRet = module:callbackOnGreet(...)
         elseif(id == CALLBACK_FAREWELL and module.callbackOnFarewell ~= nil) then
            tmpRet = module:callbackOnFarewell(...)
         elseif(id == CALLBACK_MESSAGE_DEFAULT and module.callbackOnMessageDefault ~= nil) then
            tmpRet = module:callbackOnMessageDefault(...)
         elseif(id == CALLBACK_MODULE_RESET and module.callbackOnModuleReset ~= nil) then
            tmpRet = module:callbackOnModuleReset(...)
         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)
      for search, replace in pairs(parseInfo) do
         if(replace ~= nil) then
            msg = msg:gsub(search, replace)
         end
      end

      return msg
   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, 0, true)
               self:releaseFocus(cid)
               self:say(msg)
            end
         end
      end
   end

   -- Greets a new player.
   function NpcHandler:greet(cid)
      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

   -- 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
                  elseif(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
                     self.talkStart[cid] = os.time()
                  else
                     self.talkStart = os.time()
                  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)) 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)) 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
         for i, speech in pairs(self.talkDelay) do
            if((speech.cid == nil or speech.cid == 0) and speech.time ~= nil and speech.message ~= nil) then
               if(os.mtime() >= speech.time) then
                  selfSay(speech.message)
                  self.talkDelay[i] = nil
               end
            elseif(isCreature(speech.cid) and speech.start ~= nil and speech.time ~= nil and speech.message ~= nil) then
               if(os.mtime() >= speech.time) then
                  local talkStart = (NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT and self.talkStart[speech.cid] or self.talkStart)
                  if(speech.force or (self:isFocused(speech.cid) and talkStart == speech.start)) then
                     if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
                        selfSay(speech.message, speech.cid)
                     else
                        selfSay(speech.message)
                     end
                  end

                  self.talkDelay[i] = nil
               end
            else
               self.talkDelay[i] = nil
            end
         end

         if(self:processModuleCallback(CALLBACK_ONTHINK)) then
            if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
               for _, 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) or -1 }
                  msg = self:parseMessage(msg, parseInfo)

                  self:say(msg, cid, 0, true)
                  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)
      if not isPlayer(cid) then
         return false
      end

      local distance = getNpcDistanceTo(cid) or -1
      return distance ~= -1 and 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.
   function NpcHandler:say(message, focus, delay, force)
      local force = force or false
      if(NPCHANDLER_TALKDELAY == TALKDELAY_NONE or (delay ~= nil and delay <= 0)) then
         if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
            selfSay(message, focus)
         else
            selfSay(message)
         end

         return
      end

      -- TODO: Add an event handling method for delayed messages
      table.insert(self.talkDelay, {
         cid = focus,
         message = message,
         time = os.mtime() + (delay and delay or self.talkDelayTime),
         start = os.time(),
         force = force
      })
   end
end

y npcsystem, por esto:
Código:
-- Advanced NPC System (Created by Jiddo),
-- Modified by Talaturen.

if(NpcSystem == nil) then
   -- Loads the underlying classes of the npcsystem.
   dofile(getDataDir() .. 'npc/lib/npcsystem/keywordhandler.lua')
   dofile(getDataDir() .. 'npc/lib/npcsystem/queue.lua')
   dofile(getDataDir() .. 'npc/lib/npcsystem/npchandler.lua')
   dofile(getDataDir() .. 'npc/lib/npcsystem/modules.lua')

   -- Global npc constants:

   -- Keyword nestling behavior. For more information look at the top of keywordhandler.lua
   KEYWORD_BEHAVIOR = BEHAVIOR_NORMAL_EXTENDED

   -- Greeting and unGreeting keywords. For more information look at the top of modules.lua
   FOCUS_GREETWORDS = {'hi', 'hello'}
   FOCUS_FAREWELLWORDS = {'bye', 'farewell'}

   -- The word for requesting trade window. For more information look at the top of modules.lua
   SHOP_TRADEREQUEST = {'offer', 'trade'}

   -- The word for accepting/declining an offer. CAN ONLY CONTAIN ONE FIELD! For more information look at the top of modules.lua
   SHOP_YESWORD = {'yes'}
   SHOP_NOWORD = {'no'}

   -- Pattern used to get the amount of an item a player wants to buy/sell.
   PATTERN_COUNT = '%d+'

   -- Talkdelay behavior. For more information, look at the top of npchandler.lua.
   NPCHANDLER_TALKDELAY = TALKDELAY_ONTHINK

   -- Conversation behavior. For more information, look at the top of npchandler.lua.
   NPCHANDLER_CONVBEHAVIOR = CONVERSATION_PRIVATE

   -- Constant strings defining the keywords to replace in the default messages.
   --   For more information, look at the top of npchandler.lua...
   TAG_PLAYERNAME = '|PLAYERNAME|'
   TAG_ITEMCOUNT = '|ITEMCOUNT|'
   TAG_TOTALCOST = '|TOTALCOST|'
   TAG_ITEMNAME = '|ITEMNAME|'
   TAG_QUEUESIZE = '|QUEUESIZE|'

   NpcSystem = {}

   -- Gets an npcparameter with the specified key. Returns nil if no such parameter is found.
   function NpcSystem.getParameter(key)
      local ret = getNpcParameter(tostring(key))
      if((type(ret) == 'number' and ret == 0) or ret == nil) then
         return nil
      else
         return ret
      end
   end

   -- Parses all known parameters for the npc. Also parses parseable modules.
   function NpcSystem.parseParameters(npcHandler)
      local ret = NpcSystem.getParameter('idletime')
      if(ret ~= nil) then
         npcHandler.idleTime = tonumber(ret)
      end
      local ret = NpcSystem.getParameter('talkradius')
      if(ret ~= nil) then
         npcHandler.talkRadius = tonumber(ret)
      end
      local ret = NpcSystem.getParameter('message_greet')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_GREET, ret)
      end
      local ret = NpcSystem.getParameter('message_farewell')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_FAREWELL, ret)
      end
      local ret = NpcSystem.getParameter('message_decline')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_DECLINE, ret)
      end
      local ret = NpcSystem.getParameter('message_needmorespace')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_NEEDMORESPACE, ret)
      end
      local ret = NpcSystem.getParameter('message_needspace')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_NEEDSPACE, ret)
      end
      local ret = NpcSystem.getParameter('message_sendtrade')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_SENDTRADE, ret)
      end
      local ret = NpcSystem.getParameter('message_noshop')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_NOSHOP, ret)
      end
      local ret = NpcSystem.getParameter('message_oncloseshop')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_ONCLOSESHOP, ret)
      end
      local ret = NpcSystem.getParameter('message_onbuy')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_ONBUY, ret)
      end
      local ret = NpcSystem.getParameter('message_onsell')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_ONSELL, ret)
      end
      local ret = NpcSystem.getParameter('message_missingmoney')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_MISSINGMONEY, ret)
      end
      local ret = NpcSystem.getParameter('message_needmoney')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_NEEDMONEY, ret)
      end
      local ret = NpcSystem.getParameter('message_missingitem')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_MISSINGITEM, ret)
      end
      local ret = NpcSystem.getParameter('message_needitem')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_NEEDITEM, ret)
      end
      local ret = NpcSystem.getParameter('message_idletimeout')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_IDLETIMEOUT, ret)
      end
      local ret = NpcSystem.getParameter('message_walkaway')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_WALKAWAY, ret)
      end
      local ret = NpcSystem.getParameter('message_alreadyfocused')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_ALREADYFOCUSED, ret)
      end
      local ret = NpcSystem.getParameter('message_placedinqueue')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_PLACEDINQUEUE, ret)
      end
      local ret = NpcSystem.getParameter('message_buy')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_BUY, ret)
      end
      local ret = NpcSystem.getParameter('message_sell')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_SELL, ret)
      end
      local ret = NpcSystem.getParameter('message_bought')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_BOUGHT, ret)
      end
      local ret = NpcSystem.getParameter('message_sold')
      if(ret ~= nil) then
         npcHandler:setMessage(MESSAGE_SOLD, ret)
      end

      -- Parse modules.
      for parameter, module in pairs(Modules.parseableModules) do
         local ret = NpcSystem.getParameter(parameter)
         if(ret ~= nil) then
            local number = tonumber(ret)
            if(number ~= nil and number ~= 0) then
               npcHandler:addModule(module:new())
            end
         end
      end
   end
end

o bien, usa este script de runer..
Código:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}

function onCreatureAppear(cid)            npcHandler:onCreatureAppear(cid)         end
function onCreatureDisappear(cid)          npcHandler:onCreatureDisappear(cid)         end
function onCreatureSay(cid, type, msg)         npcHandler:onCreatureSay(cid, type, msg)      end
function onThink()               npcHandler:onThink()               end

local shopModule = ShopModule:new()
npcHandler:addModule(shopModule)

shopModule:addBuyableItem({'spellbook'}, 2175, 150, 'spellbook')
shopModule:addBuyableItem({'magic lightwand'}, 2163, 400, 'magic lightwand')

shopModule:addBuyableItem({'small health'}, 8704, 20, 1, 'small health potion')
shopModule:addBuyableItem({'health potion'}, 7618, 45, 1, 'health potion')
shopModule:addBuyableItem({'mana potion'}, 7620, 50, 1, 'mana potion')
shopModule:addBuyableItem({'strong health'}, 7588, 100, 1, 'strong health potion')
shopModule:addBuyableItem({'strong mana'}, 7589, 80, 1, 'strong mana potion')
shopModule:addBuyableItem({'great health'}, 7591, 190, 1, 'great health potion')
shopModule:addBuyableItem({'great mana'}, 7590, 120, 1, 'great mana potion')
shopModule:addBuyableItem({'great spirit'}, 8472, 190, 1, 'great spirit potion')
shopModule:addBuyableItem({'ultimate health'}, 8473, 310, 1, 'ultimate health potion')
shopModule:addBuyableItem({'antidote potion'}, 8474, 50, 1, 'antidote potion')

shopModule:addSellableItem({'normal potion flask', 'normal flask'}, 7636, 5, 'empty small potion flask')
shopModule:addSellableItem({'strong potion flask', 'strong flask'}, 7634, 10, 'empty strong potion flask')
shopModule:addSellableItem({'great potion flask', 'great flask'}, 7635, 15, 'empty great potion flask')

shopModule:addBuyableItem({'instense healing'}, 2265, 95, 1, 'intense healing rune')
shopModule:addBuyableItem({'ultimate healing'}, 2273, 175, 1, 'ultimate healing rune')
shopModule:addBuyableItem({'magic wall'}, 2293, 350, 3, 'magic wall rune')
shopModule:addBuyableItem({'destroy field'}, 2261, 45, 3, 'destroy field rune')
shopModule:addBuyableItem({'light magic missile'}, 2287, 40, 10, 'light magic missile rune')
shopModule:addBuyableItem({'heavy magic missile'}, 2311, 120, 10, 'heavy magic missile rune')
shopModule:addBuyableItem({'great fireball'}, 2304, 180, 4, 'great fireball rune')
shopModule:addBuyableItem({'explosion'}, 2313, 250, 6, 'explosion rune')
shopModule:addBuyableItem({'sudden death'}, 2268, 350, 3, 'sudden death rune')
shopModule:addBuyableItem({'death arrow'}, 2263, 300, 3, 'death arrow rune')
shopModule:addBuyableItem({'paralyze'}, 2278, 700, 1, 'paralyze rune')
shopModule:addBuyableItem({'animate dead'}, 2316, 375, 1, 'animate dead rune')
shopModule:addBuyableItem({'convince creature'}, 2290, 80, 1, 'convince creature rune')
shopModule:addBuyableItem({'chameleon'}, 2291, 210, 1, 'chameleon rune')
shopModule:addBuyableItem({'desintegrate'}, 2310, 80,  3, 'desintegreate rune')

shopModule:addBuyableItem({'wand of vortex', 'vortex'}, 2190, 500, 'wand of vortex')
shopModule:addBuyableItem({'wand of dragonbreath', 'dragonbreath'}, 2191, 1000, 'wand of dragonbreath')
shopModule:addBuyableItem({'wand of decay', 'decay'}, 2188, 5000, 'wand of decay')
shopModule:addBuyableItem({'wand of draconia', 'draconia'}, 8921, 7500, 'wand of draconia')
shopModule:addBuyableItem({'wand of cosmic energy', 'cosmic energy'}, 2189, 10000, 'wand of cosmic energy')
shopModule:addBuyableItem({'wand of inferno', 'inferno'}, 2187, 15000, 'wand of inferno')
shopModule:addBuyableItem({'wand of starstorm', 'starstorm'}, 8920, 18000, 'wand of starstorm')
shopModule:addBuyableItem({'wand of voodoo', 'voodoo'}, 8922, 22000, 'wand of voodoo')

shopModule:addBuyableItem({'snakebite rod', 'snakebite'}, 2182, 500, 'snakebite rod')
shopModule:addBuyableItem({'moonlight rod', 'moonlight'}, 2186, 1000, 'moonlight rod')
shopModule:addBuyableItem({'necrotic rod', 'necrotic'}, 2185, 5000, 'necrotic rod')
shopModule:addBuyableItem({'northwind rod', 'northwind'}, 8911, 7500, 'northwind rod')
shopModule:addBuyableItem({'terra rod', 'terra'}, 2181, 10000, 'terra rod')
shopModule:addBuyableItem({'hailstorm rod', 'hailstorm'}, 2183, 15000, 'hailstorm rod')
shopModule:addBuyableItem({'springsprout rod', 'springsprout'}, 8912, 18000, 'springsprout rod')
shopModule:addBuyableItem({'underworld rod', 'underworld'}, 8910, 22000, 'underworld rod')

shopModule:addSellableItem({'wand of vortex', 'vortex'}, 2190, 250, 'wand of vortex')
shopModule:addSellableItem({'wand of dragonbreath', 'dragonbreath'}, 2191, 500, 'wand of dragonbreath')
shopModule:addSellableItem({'wand of decay', 'decay'}, 2188, 2500, 'wand of decay')
shopModule:addSellableItem({'wand of draconia', 'draconia'}, 8921, 3750, 'wand of draconia')
shopModule:addSellableItem({'wand of cosmic energy', 'cosmic energy'}, 2189, 5000, 'wand of cosmic energy')
shopModule:addSellableItem({'wand of inferno', 'inferno'},2187, 7500, 'wand of inferno')
shopModule:addSellableItem({'wand of starstorm', 'starstorm'}, 8920, 9000, 'wand of starstorm')
shopModule:addSellableItem({'wand of voodoo', 'voodoo'}, 8922, 11000, 'wand of voodoo')

shopModule:addSellableItem({'snakebite rod', 'snakebite'}, 2182, 250,'snakebite rod')
shopModule:addSellableItem({'moonlight rod', 'moonlight'}, 2186, 500,  'moonlight rod')
shopModule:addSellableItem({'necrotic rod', 'necrotic'}, 2185, 2500, 'necrotic rod')
shopModule:addSellableItem({'northwind rod', 'northwind'}, 8911, 3750, 'northwind rod')
shopModule:addSellableItem({'terra rod', 'terra'}, 2181, 5000, 'terra rod')
shopModule:addSellableItem({'hailstorm rod', 'hailstorm'}, 2183, 7500, 'hailstorm rod')
shopModule:addSellableItem({'springsprout rod', 'springsprout'}, 8912, 9000, 'springsprout rod')
shopModule:addSellableItem({'underworld rod', 'underworld'}, 8910, 11000, 'underworld rod')

local items = {[1] = 2190, [2] = 2182, [5] = 2190, [6] = 2182}
function creatureSayCallback(cid, type, msg)
   if(not npcHandler:isFocused(cid)) then
      return false
   end

   local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid
   if(msgcontains(msg, 'first rod') or msgcontains(msg, 'first wand')) then
      if(isSorcerer(cid) or isDruid(cid)) then
         if(getPlayerStorageValue(cid, 50111) <= 0) then
            selfSay('So you ask me for a {' .. getItemNameById(items[getPlayerVocation(cid)]) .. '} to begin your advanture?', cid)
            talkState[talkUser] = 1
         else
            selfSay('What? I have already gave you one {' .. getItemNameById(items[getPlayerVocation(cid)]) .. '}!', cid)
         end
      else
         selfSay('Sorry, you aren\'t a druid either a sorcerer.', cid)
      end
   elseif(msgcontains(msg, 'yes')) then
      if(talkState[talkUser] == 1) then
         doPlayerAddItem(cid, items[getPlayerVocation(cid)], 1)
         selfSay('Here you are young adept, take care yourself.', cid)
         setPlayerStorageValue(cid, 50111, 1)
      end
      talkState[talkUser] = 0
   elseif(msgcontains(msg, 'no') and isInArray({1}, talkState[talkUser])) then
      selfSay('Ok then.', cid)
      talkState[talkUser] = 0
   end

   return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

XML:
Código:
<?xml version="1.0" encoding="UTF-8"?>
<npc name="Eryn" nameDescription="Eryn, the rune vendor" script="runes.lua" walkinterval="2000" floorchange="0" skull="green">
   <health now="100" max="100"/>
   <look type="130" head="39" body="122" legs="125" feet="57" addons="0"/>
   <parameters>
      <parameter key="message_greet" value="Hello |PLAYERNAME|. I sell runes, potions, wands and rods."/>
      <parameter key="message_decline" value="Is |TOTALCOST| gold coins too much for you? Get out of here!"/>
   </parameters>
</npc>

Si no funciona, utiliza http://www.othispano.net/t678-860-otx-server-version-21simple?highlight=simple

Saludos.

El autor de este mensaje ha sido baneado del foro - Ver el mensaje

Contenido patrocinado

npc y runas ayuda Empty Re: npc y runas ayuda

Volver arriba
Permisos de este foro:
No puedes responder a temas en este foro.