• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Tutorial Fixy

Status
Not open for further replies.
Code:
-- 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 = 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.
        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

znalazłem też inną wersję NPCHANDLER.LUA
 
nie jestem pewny.. więć spytam
Code:
function onDirection(cid, old, current)
	local storage = 123456
	local triesStorage = 123457
	local set = 0
 
	if (exhaustion.check(cid, storage)) then
		local tries = getCreatureStorage(cid, triesStorage)
 
		if (tries >= 5) then
			doCreatureAddHealth(cid, -(getCreatureMaxHealth(cid) * 0.25))
		else
			set = tries + 1
		end
	end
 
	doCreatureSetStorage(cid, triesStorage, set)
	exhaustion.make(cid, storage, 1)
	return true
end

To skrypt z kategorii creaturescripts? i co dodać w creaturescripts.xml jeśli tak.
pzdr..
 
creaturevent.cpp tam masz wszystkie rodzaje eventow, wiec sobie znajdz.

@Topic:
OP is a fag i chuj wie, postuje fixy bez podawania przyczyn bledow, wiec raczej gowno sie zna i postuje rzeczy, na ktorych temat nic nie wie i wie tylko ze mozna nimi zrobic niezly reap silnika.
 
Hmm pomyślmy, mając do dyspozycji source i widząc nazwę funkcji nie wiem w czym problem wystarczy poszukać a jak się nie chcę to może pomyśleć bo jak widzę to przychodzi ciężej. Nie wiem co może być trudnego w zadeklarowaniu tego w *.xml
 
Ok, wczesniej nie mialem czasu zeby to napisac.

@OP:
1. Po szybkiej analizie funkcji doNpcSellItem w Twoim NPC.lua stwierdzam, ze nawaliles exhaustion.set byle gdzie nie wiedzac co robisz, mozna by bylo z polowe ich wywalic.
2. Zamiast postowac NPCHandler.lua to postnalbys konkretne linijki, jak ktos uzywa nowszego liba i przerzuci caly Twoj to moga mu niedzialac nie ktore funkcje.
3. Czemu akurat 7k capa? Rownie dobrze moze to byc i 5k, albo 6k. Nie wiem dlaczego wybrales akurat ta liczbe.
4. Nieudana liczba prob logowan? Skrypt + proxy + jakis maly delay i niech sobie crackuje cala noc.
5. Dobra reCaptcha? reCaptcha jest tylko jedna, jest to system captcha Google i nie ma czegos takiego jak dobra i slaba reCaptcha.
6. exaBotDefender? W zakresie OTSów malo przydatny.
7. Exhaust na komende w db, fajnie to okresliles. lrn2querycache ;]
8. "8.6 - Limit itemów na kratkę wszędzie! Najlepiej koło 70." Czemu tylko 8.6 i czemu akurat 70? 70 imho. stanowczo za duzo, pozatym przerzucic sobie latwo mozna feature, nie wiem czemu akurat podales tutaj wersje protokolu, a nie np. konkretnego reva z tym featurem.
9. "8.54 - w drzwiach lvlowych zrobić takiego sqm żeby nic nie można było rzucać, quest doors także oraz mostki - Pozdrowienia w strone Cipsoftu ;d" Idk. czemu akurat 8.54, taki feature przydalby sie we wszystkich wersjach.
10. "Ciekawy jestem jak by to było gdyby nikt nikogo nie dał rady dojechać ;>" Oprocz DoSa (W przypadku TFSa CPU reap) przeciez zawsze mozna zapchac traffic (jakis botnet czy cos, czy miliony chinczykow wciskajacych F5 na Twojej stronie, heh).
11. Dance Debug? Wystarczy, zebys w source dac jakas zmienna dla playera i potem sprawdzac czy ostatni ruch byl zrobiony powiedzmy <0.5 sec temu, jak tak to nie robic zadnej akcji. Po co executowac skrypt przy kazdej zmianie kierunku?


Ja w hosteam mając chyba ze 20mb nigdy nie zostałem dotknięty przez ping.
A miałem ponad 1000 graczy.
Nie wiem czemu wszyscy tak uciekaja do tego Hosteamu, siadaly takze otsy hostowane u tej firmy.

Oj synek, to nie temat na takie rozmowy, wiele osób to sprawdzało, zapytaj kuli czy tam samme.
Ale tez mi nie powiesz, synek, ze wszyscy to byli prawdziwi gracze, wiekszosc to i tak byl jakis bot na trainerach/multiclienty. Ciekaw jestem ile bylo unikalnych polaczen.

@ http://otland.net/f28/fixy-121228/index4.html#post1186486
Imho. to tez zalezy od konfiguracji sprzetowej, mam na mysli, ze wartosci z configu przekladaja sie na sprzet. Ale nie chce sie wyklucac, bo nie jestem pewien.

@ http://otland.net/f28/fixy-121228/index5.html#post1186576
>Best Guilds
>Query Cache Topic
>Trolling.png

@ http://otland.net/f28/fixy-121228/index6.html#post1188686
Zmieniliby gre (Np. WoW, Metin2), albo by nabyli cos zwane "Real Lifem".

Ole! Pozdrawiam wszystkich pseudo-specjalistow (Nie, nie mam na mysli uzytkownika View Profile: Specjalist - OtLand).
 
Ok, wczesniej nie mialem czasu zeby to napisac.

@OP:
1. Po szybkiej analizie funkcji doNpcSellItem w Twoim NPC.lua stwierdzam, ze nawaliles exhaustion.set byle gdzie nie wiedzac co robisz, mozna by bylo z polowe ich wywalic.
2. Zamiast postowac NPCHandler.lua to postnalbys konkretne linijki, jak ktos uzywa nowszego liba i przerzuci caly Twoj to moga mu niedzialac nie ktore funkcje.
3. Czemu akurat 7k capa? Rownie dobrze moze to byc i 5k, albo 6k. Nie wiem dlaczego wybrales akurat ta liczbe.
4. Nieudana liczba prob logowan? Skrypt + proxy + jakis maly delay i niech sobie crackuje cala noc.
5. Dobra reCaptcha? reCaptcha jest tylko jedna, jest to system captcha Google i nie ma czegos takiego jak dobra i slaba reCaptcha.
6. exaBotDefender? W zakresie OTSów malo przydatny.
7. Exhaust na komende w db, fajnie to okresliles. lrn2querycache ;]
8. "8.6 - Limit itemów na kratkę wszędzie! Najlepiej koło 70." Czemu tylko 8.6 i czemu akurat 70? 70 imho. stanowczo za duzo, pozatym przerzucic sobie latwo mozna feature, nie wiem czemu akurat podales tutaj wersje protokolu, a nie np. konkretnego reva z tym featurem.
9. "8.54 - w drzwiach lvlowych zrobić takiego sqm żeby nic nie można było rzucać, quest doors także oraz mostki - Pozdrowienia w strone Cipsoftu ;d" Idk. czemu akurat 8.54, taki feature przydalby sie we wszystkich wersjach.
10. "Ciekawy jestem jak by to było gdyby nikt nikogo nie dał rady dojechać ;>" Oprocz DoSa (W przypadku TFSa CPU reap) przeciez zawsze mozna zapchac traffic (jakis botnet czy cos, czy miliony chinczykow wciskajacych F5 na Twojej stronie, heh).
11. Dance Debug? Wystarczy, zebys w source dac jakas zmienna dla playera i potem sprawdzac czy ostatni ruch byl zrobiony powiedzmy <0.5 sec temu, jak tak to nie robic zadnej akcji. Po co executowac skrypt przy kazdej zmianie kierunku?



Nie wiem czemu wszyscy tak uciekaja do tego Hosteamu, siadaly takze otsy hostowane u tej firmy.


Ale tez mi nie powiesz, synek, ze wszyscy to byli prawdziwi gracze, wiekszosc to i tak byl jakis bot na trainerach/multiclienty. Ciekaw jestem ile bylo unikalnych polaczen.

@ http://otland.net/f28/fixy-121228/index4.html#post1186486
Imho. to tez zalezy od konfiguracji sprzetowej, mam na mysli, ze wartosci z configu przekladaja sie na sprzet. Ale nie chce sie wyklucac, bo nie jestem pewien.

@ http://otland.net/f28/fixy-121228/index5.html#post1186576
>Best Guilds
>Query Cache Topic
>Trolling.png

@ http://otland.net/f28/fixy-121228/index6.html#post1188686
Zmieniliby gre (Np. WoW, Metin2), albo by nabyli cos zwane "Real Lifem".

Ole! Pozdrawiam wszystkich pseudo-specjalistow (Nie, nie mam na mysli uzytkownika View Profile: Specjalist - OtLand).

No już Ci odpowiadam.
1. To ma działać, a nie wyglądać, a działa dobrze. Nie pierdole się jak nie mam na coś czasu i jest to moja dobra wola a nie praca więc nie wiem po co ten post ale ok.
2. Tak, bylbym w stanie to zrobic.
3. Akurat 7k capa, na większości otsów na których to sprawdzałem potrzebne było około 8k.
4. Nie bardzo widze sens mojej odpowiedzi.
5. Dobra skoro jesteś taki dokładny to miałem na myśli CYFERKI DO PRZEPISANIA Z OBRAZKA.
6. Mało przydatny powiadasz? Spoko, na jakiej podstawie tak twierdzisz? Mało przydatny?
Bo ja jestem w stanie udowodnić, że blokuje to kilka sposobów na atak przez stronę.
7. Tak, wiem że fajnie wszystko określam, ja robie proste i działające fixy, w dupie to mam że można to zrobić lepiej ;]
8. Już Ci mówie, bo w 8.6 jest w configu opcja w którym można dać limit na ilość itemów.
Na 8.54 takiego czegoś nie ma, chyba że sam sobie dorobisz.

Naprawdę nie muszę nic nikomu udowadniać bo ja swoje osiągnąłem i swoje wiem. Może nie jestem jakimś specjalistą, ale wielu ich przebiłem razem z grześkiem :) Jak jesteś taki dociekliwy to poszukaj tematu gdzie Kula czy Samme dogłębnie sprawdzili graczy na naszym Serwerze, jakbyś nie urodził się wczoraj to byś wiedział ^^ kmwtw.
I nie jestem Twoim synkiem.

Jednym słowem, trollujesz bo nic nowego do tematu nie wprowadzasz, a to, że można zrobić coś lepiej niż ja polecam to wiadomo. Zawsze można coś zrobić lepiej ;]
Nie mam zamiaru więcej odbijać piłeczki. Papa

Samme kasuj takie Trollowanie, thx.
 
Last edited:
No już Ci odpowiadam.
1. To ma działać, a nie wyglądać, a działa dobrze. Nie pierdole się jak nie mam na coś czasu i jest to moja dobra wola a nie praca więc nie wiem po co ten post ale ok.
2. Tak, bylbym w stanie to zrobic.
3. Akurat 7k capa, na większości otsów na których to sprawdzałem potrzebne było około 8k.
4. Nie bardzo widze sens mojej odpowiedzi.
5. Dobra skoro jesteś taki dokładny to miałem na myśli CYFERKI DO PRZEPISANIA Z OBRAZKA.
6. Mało przydatny powiadasz? Spoko, na jakiej podstawie tak twierdzisz? Mało przydatny?
Bo ja jestem w stanie udowodnić, że blokuje to kilka sposobów na atak przez stronę.
7. Tak, wiem że fajnie wszystko określam, ja robie proste i działające fixy, w dupie to mam że można to zrobić lepiej ;]
8. Już Ci mówie, bo w 8.6 jest w configu opcja w którym można dać limit na ilość itemów.
Na 8.54 takiego czegoś nie ma, chyba że sam sobie dorobisz.

Jednym słowem, trollujesz bo nic nowego do tematu nie wprowadzasz, a to, że można zrobić coś lepiej niż ja polecam to wiadomo. Zawsze można coś zrobić lepiej ;]
Nie mam zamiaru odbijać piłeczki. Papa


1. Piszesz tutaj, ze to jest dobra wola, ze udostepniasz to, a jestem w 100% przekonany, ze identycznego kodu uzywales u siebie - czyli caly chuj w prace wlozyles.
2. To dlaczego od razu tego nie zrobiles?
3. No to skoro mowisz, ze okolo 8k, to czemu napisales 7, a nie 8. Aff men, nie pograzaj sie.
4. Moze nie wiesz co powiedziec?
5. Tak sie akurat sklada, ze te gesiorowe cyferki to crap i wiem, ze ktos ma na to crackera.
6. Patchnij sobie AAC, tak zeby filtrowac wszystkie mozliwe ataki i nie bedzie Ci potrzebny. No tak, ale my tu mowimy o gnojku, ktory caly chuj wie o web dev. i bedzie stal murem za swoim shitsiorem (Czyt. Gesior AAC).
7. A co maja fixy do okreslenia? .oO
8. No toz chyba przed chwila napisalem, co lepiej byloby zrobic, po co sie znowu pograzasz.

Trolluje? Tylko dlatego, ze wpadam z argumentami, ktore swiadcza o Twojej niekompetencji? Wszyscy dobrze wiemy, ze Ty i ten Twoj Grzechopl to caly chuj umiecie w tych OTSach i do kazdego plakaliscie o pomoc.

Feel like gettin' pwnt?
 
Ludzie czy Wy nie możecie normalnie rozmawiać, czy większość wypowiedzi musi sprowadzać się do wyzwisk??? Po co to komu, co sobie tym udowadniacie??? Wszystko da się wyjaśnić na spokojnie a poprzez wyzwiska i mieszanie drugiej osoby z błotem. Więcej szacunku a mniej wyzwisk i wszystkim będzie rozmawiało się lepiej.
 
1&2 Tak, używałem u siebie i co z tego? Co cie obchodzi ile pracy w coś włożyłem? Nie chce się już powtarzać - dla mnie jak coś działa to działa i w dupie mam czy ma 6 linijek kodu czy 12.
3. Z czystej logiki? Skoro wystarczy 8k do wywalenia to limit na 7k będzie w sam raz?
4. Moze mam cie troche w dupie, ale nie będzie mnie jakiś śmieć który gówno osiągnął poniżał?
5&6 Od jakiegoś czasu miałem już swojego przepisanego ACC. Dlaczego zakładasz coś czego nie wiesz?


O mojej niekompetencji? Kiedy ty zabijałeś szczury w Thais ja broniłem się przez Sasirem bo wszystkie ataki leciały na mnie, także gówno Ci do tego z kim się konsultowaliśmy, a konsultowaliśmy się z wieloma osobami i jakoś wszystkim specjalistom mowe odbierało bo nikt nie wiedział co i dlaczego, zwykłe gadanie głupot (było kilka wyjątków) a potem tylko pytanie - No i co było?
Kiedy wszystkie otsy padały od zwykłych pingów - nasz stał i był atakowany na wiele wiele innych sposobów, taka jest prawda i wmawiaj sobie co chcesz nic nie zmieni tego faktu.
Prawda jest taka ja>ty.

Otland zszedł na psy. Wykażesz dobrą wole pomocy to wejdzie jakiś szczyl i zacznie szukać dziur w całym.
Tym razem piłeczka została w 100% odbita przezemnie ostatni raz. Kto ma wiedzieć ten wie, nie zależy mi w sumie na opinii wściekłych dzieci tibia.
Żegnam.
 
Last edited:
@ 1/2. Aktualnie nie chodzi tu o linijki, a o jakosc i efektywnosc kodu, jak bedziesz robic cos byle jak to bedzie to prowadzilo do waste resourcow i/lub nawet do crasha/lagow.
@ 4. Dla Ciebie jestem smieciem teraz, tak? A jak stala Tyrania to grzesiek/Ty co drugi dzien do mnie via GG spamiliscie pomoz to, pomoz tamto, podstawowych rzeczy nie potrafiliscie, wiec nie afiszuj sie jaki ty masz skill teraz, bo wiem, ze szczerze to caly chuj potrafisz.
@ 5/6. Jezeli Ty byles autorem tego swojego AAC (Nie pisze sie ACC, tylko AAC btw.) to moge z pewnoscia powiedziec, ze znalazlbym tam nie jeden SQL-I lub inny security hole.

O mojej niekompetencji? Kiedy ty zabijałeś szczury w Thais ja broniłem się przez Sasirem bo wszystkie ataki leciały na mnie, także gówno Ci do tego z kim się konsultowaliśmy, a konsultowaliśmy się z wieloma osobami i jakoś wszystkim specjalistom mowe odbierało bo nikt nie wiedział co i dlaczego, zwykłe gadanie głupot (było kilka wyjątków) a potem tylko pytanie - No i co było?
Kiedy wszystkie otsy padały od zwykłych pingów - nasz stał i był atakowany na wiele wiele innych sposobów, taka jest prawda i wmawiaj sobie co chcesz nic nie zmieni tego faktu.
Prawda jest taka ja>ty.

Nie znasz mnie, to co mowisz, ze ja jakie szczury trzaskalem, a Ty sie broniles przed atakami Sasira. Prawda jest taka, ze pewnie nie byliscie tacy zachlanni na hajs jak inni, i wylozyliscie troche kwitu na jakis pozadny firewall czy cos.
Ty > Ja? Ok, spoko. Dalej siedz w swoich skretynialych przekonaniach, ze jezeli nie oberwales DDoSem i ze miales 1k+ ppl. na serwie to, ze jestes mistrzem nad mistrzami i masz o wszystkim pojecie.


Otland zszedł na psy. Wykażesz dobrą wole pomocy to wejdzie jakiś szczyl i zacznie szukać dziur w całym.
Tym razem piłeczka została w 100% odbita przezemnie ostatni raz. Kto ma wiedzieć ten wie, nie zależy mi w sumie na opinii wściekłych dzieci tibia.
Żegnam.


Chodzi o to, ze sie kurwo afiszujesz jaki Ty jestes niezly, ze Ty miales najlepszy OTS, ze inni to 0, bo Twoj OTS nie dostal DDoSa i stal z 1k+ ppl.
>Wscieklych dzieci tibia.
Znowu, wyciagasz pochopne wnioski na moj temat, nawet mnie nie znajac i tutaj mam nad Toba przewage, bo Ty mnie nie znasz, a ja znam i Twoje slowa to tylko wyssane z palca, a moje to prawda, ktora rani Cie jak murzynski penis w dupe.

Z mojej strony tez juz wszystko, elo p. specjalisto.
 
A cały sukces tyranii mozecie zawdzieczyc dorwaniu dobrego hostingu we wlasiwym czasie;]
 
Last edited:
Super Aac czy Acc akurat tutaj miałem na myśli skrót od Account - mam dopisać Maker? Chcesz o tym rozmawiać?
Nie uważam się za kogoś z mega wielkimi umiejętnościami, bo takim kimś nie jestem, mimo to potrafiłem się dobrze zakręcić i sam sobie z grzeskiem radzić w trudnych chwilach. Ten kto ze mną pracował, wie co umiem. Jasne że miałem wiele postów na forum, requesty, poprawy błędów, nikt od razu nie jest ekspertem. Pomogło nam kilka osób dla których dziękuje, jak widzisz nikt się tym nie afiszuje, a ty chwalisz się tym, że o coś cie pytaliśmy, super, pomogłeś? Nie, więc po co do tego nawiązujesz?
Gdzie poprzednio widziałeś, żebym się przechwalał? Sam na mnie wsiadłeś. Może wracasz do starych czasów? tak wtedy się bardzo afiszowaliśmy, ale jakbyś pomyślał, to wiedziałbyś po co.
Podkreśle, że jesteś jednym z tych który najpierw na nas wsiadał, potem się do nas pucował, bo tak było i nie gadaj, że nie.
Drażni Cie fakt, że może więcej potrafisz, ale nie potrafisz tego wykorzystać. Ostatnim razem rozmawialiśmy jeszcze na poziomie, tak więc nie wiem co się zmieniło od tego czasu, może dopadła cie w końcu zazdrość.
Smutno mi z tego powodu.

A cały sukces tyranii mozecie zawdzieczyc dorwaniu dobrego hostingu we wlasiwym czasie;]
Kret, na prawdę myślisz, że hosting nas przed wszystkim bronił? Nie potrafie zliczyć ilość sposobów atakowania przez Sasira.
Mieliśmy kilka dobrych pomysłów na reklamę, na zachęcenie ludzi do gry. Ile osób skopiowało pomysł na turniej Gildii? Tak na prawdę jest wiele czynników które składają się na sukces, także nie do końca trafiłeś tym postem.


P.S Robi się nam tutaj wielki offtop.
 
Last edited:
A cały sukces tyranii mozecie zawdzieczyc dorwaniu dobrego hostingu we wlasiwym czasie;]

Chcialbym zobaczyc taka tyranie na ovh ;]

Niezle by sie tyrala z DDoSami sasira

Kret, na prawdę myślisz, że hosting nas przed wszystkim bronił? Nie potrafie zliczyć ilość sposobów atakowania przez Sasira.

No niby jak jeszcze was sasirek atakowal? UDP Flood i co jeszcze? Moze uzywal "pingu" ;> ?
 
Jak by nie liczyła się pomoc HosTeam'u to Dulin by poradził sobie bez niego w atakach.
 
A pamietacie jak Sasir odpierdolil akcje z dotpayem?
 
Czy naprawdę myślicie, że jedynym sposobem na to był atak z zewnątrz?

@kret
Nie powiedziałem, że pomoc hosteamu się nie liczyła.
 
triamera mówiłeś że spierdalasz z otlandu to co jeszcze siedzisz nara nikt cię nie potrzebuje i twoich bajeczek
 
Status
Not open for further replies.
Back
Top