• 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!
  • New resources must be posted under Resources tab. A discussion thread will be created automatically, you can't open threads manually anymore.

Advanced Task NPC

I tested it on TFS 1.3.

Some bugs:
If u don't say "Bye" to npc he is always in talk with you everywhere,
I finish Rats task, if i was trying to start Troll task it take me back co Rats task.
 
Converted to Modal Windows

Creaturescript.xml
Code:
<event type="modalwindow" name="TaskSystemWindow" script="TaskSystemWindow.lua" />
<event type="kill" name="TaskSystemKill" script="TaskSystemKill.lua" />

add creaturescript: TaskSystemWindow.lua
Code:
local npcMissions = {
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    [1] = {name = "Rat Killer", -- Kill monsters only
        arrayName = {"Rat", "rat", "Rats", "rats", "Pest", "pest", "Pests", "pests", "rat killer", "Rat killer", "Rat Killer"},
        storageMission = 43000, -- Mission storage should be unique even in different NPC files.
        storageRequired = nil, -- Use this to require different tasks to be done complete before this task can be started.
        messageTaskInfo = "I need you to kill 10 rats and 10 cave rats.", -- This message is said to the player when he starts the task.
        messageTaskComplete = "Thank you! Those pests have ruined my store. unfortunately they will be back. The rats aren't the main {problem}", -- This message is said to the player when he finishs the task.
        windowMsg = "Kill rats in the basement.", -- This text is shown under the title of the modal window
        monsters = { -- Monster task
            [1] = {name = "Rat", amount = 10, storage = 41000}, -- Monster storages should be unique even in different NPC files.
            [2] = {name = "Cave Rat", amount = 10, storage = 41001}
        },
        --Rewards--
        exp = 1000, -- Exp given to the player for completing the task.
        rewardItems = { -- Items given to the player for completing the task.
            [1] = {itemid = 2390, amount = 1}
        },
        setStorage = nil -- Use this to set any storages you want to when the player completes the task excluding storageNpc and storageMission
    },
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    [2] = {name = "Troll Hunter",
        arrayName = {"troll hunter", "Troll Hunter", "Troll", "troll", "Trolls", "trolls"},
        storageMission = 43001,
        storageRequired = {43000},
        messageTaskInfo = "I need you to kill 20 trolls.",
        messageTaskComplete = "You are truley a legend. There is one more thing I need. Could you {help} me one more time?",
        windowMsg = "Kill trolls in the forst to the east. Also, collect x items",
        monsters = {
            [1] = {name = "Troll", amount = 20, storage = 41002},
        },
        collectItems = { -- Collect Items task
            [1] = {itemid = 1111, amount = 1}
        },
        --Rewards--
        exp = 5000,
        rewardItems = {
            [1] = {itemid = 2390, amount = 1}
        },
        setStorage = {
            [1] = {41532, 1}
        }
    },
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    [3] = {name = "The Collector", -- Collect Items only
        arrayName = {"collector", "Collector", "collect", "Collect", "cheese", "Cheese"},
        storageMission = 43003,
        storageRequired = {43001, 43002},
        messageTaskInfo = "I need you to collect 10 cheese.",
        messageTaskComplete = "You are truley a legend. I do not need anymore help.",
        windowMsg = "Collect x items",
        collectItems = { -- Collect Items task
            [1] = {itemid = 1111, amount = 1}
        },
        --Rewards--
        exp = 5000,
        rewardItems = {
            [1] = {itemid = 2390, amount = 1}
        },
        setStorage = nil
    }
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
}

function onModalWindow(player, modalWindowId, buttonId, choiceId)
    if modalWindowId == 0x10 then
        if buttonId == 0x01 then
            local TASK = npcMissions[choiceId]
           
            if not TASK then print('Internal Error finding Task') return false end
            if player:getStorageValue(TASK.storageMission) == 2 then
                local window = ModalWindow(0x12, TASK.name, TASK.windowMsg)
                window:addChoice(0x00, "You have already completed this task.")
                window:addButton(0x00, "Exit")
                window:setDefaultEnterButton(0x00)
                window:sendToPlayer(player)
                return true
            elseif player:getStorageValue(TASK.storageMission) == 1 then
                local window = ModalWindow(0x12, TASK.name, TASK.windowMsg)
                local count = 1
                if TASK.monsters then
                    for i = 1, #TASK.monsters do
                        window:addChoice(count, "("..player:getStorageValue(TASK.monsters[i].storage).."/"..TASK.monsters[i].amount.." "..TASK.monsters[i].name..".")
                        count = count + 1
                    end
                end
               
                if TASK.collectItems then
                    for i = 1, #TASK.collectItems do
                        window:addChoice(count, "("..player:getItemCount(TASK.collectItems[i].itemid).."/"..TASK.collectItems[i].amount.." "..ItemType(TASK.collectItems[i].itemid):getName()..".")
                        count = count + 1
                    end
                end
               
                window:addButton(0x00, "Exit")
                window:addButton(choiceId, "Turn-In")
                window:setDefaultEnterButton(0x01)
                window:sendToPlayer(player)
                return true
               
            elseif player:getStorageValue(TASK.storageMission) == -1 then
                local window = ModalWindow(0x11, TASK.name, TASK.windowMsg)
                local count = 1
                if TASK.monsters then
                    for i = 1, #TASK.monsters do
                        window:addChoice(count, "Kill: "..TASK.monsters[i].amount.." "..TASK.monsters[i].name..".")
                        count = count + 1
                    end
                end
               
                if TASK.collectItems then
                    for i = 1, #TASK.collectItems do
                        window:addChoice(count, "Collect: "..TASK.collectItems[i].amount.." "..ItemType(TASK.collectItems[i].itemid):getName()..".")
                        count = count + 1
                    end
                end
               
                window:addButton(0x00, "Exit")
                window:addButton(choiceId, "Accept")
                window:setDefaultEnterButton(0x01)
                window:sendToPlayer(player)
                return true
            end
            return true
        end
   
    elseif modalWindowId == 0x11 then
            local TASK = npcMissions[buttonId]
       
            if not TASK then print('Internal Error finding Task') return false end
       
            player:setStorageValue(TASK.storageMission, 1)
       
            if TASK.monsters then
                for i = 1, #TASK.monsters do
                    player:setStorageValue(TASK.monsters[i].storage, 0)
                end
            end
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You have started: "..TASK.name.."!")
            return true
           
    elseif modalWindowId == 0x12 then
            local TASK = npcMissions[buttonId]
           
            if not TASK then print('Internal Error finding Task') return false end
           
            local canTurnIn = true
           
            if TASK.monsters then
                for i = 1, #TASK.monsters do
                    if player:getStorageValue(TASK.monsters[i].storage) < TASK.monsters[i].amount then
                        canTurnIn = false
                    end
                end
            end
           
            if TASK.collectItems then
                for i = 1, #TASK.collectItems do
                    if player:getItemCount(TASK.collectItems[i].itemid) < TASK.collectItems[i].amount then
                        canTurnIn = false
                    end
                end
            end
           
            if canTurnIn then
                if TASK.monsters then
                    for i = 1, #TASK.monsters do
                        player:setStorageValue(TASK.monsters[i].storage, -1)
                    end
                end
           
                if TASK.collectItems then
                    for i = 1, #TASK.collectItems do
                        player:removeItem(TASK.collectItems[i].itemid, TASK.collectItems[i].amount)
                    end
                end
               
                player:setStorageValue(TASK.storageMission, 2)
               
                if TASK.exp then
                    player:addExperience(TASK.exp)
                end
               
                if TASK.rewardItems then
                    for i = 1, #TASK.rewardItems do
                        player:addItem(TASK.rewardItems[i].itemid, TASK.rewardItems[i].amount, true)
                    end
                end
               
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You have completed: "..TASK.name.."!")
            else
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You are not ready to turn in this task.")
            end
        end
    return true
end

add creaturescript: TaskSystemKill.lua
Code:
local missions = { -- Use missionStorage to link the monsters to each mission. It is set up this way so multiple missions can have the same monsters.
    [1] = {name = "Rat", amount = 10, missionStorage = 43000, storage = 41000},
    [2] = {name = "Cave Rat", amount = 10, missionStorage = 43000, storage = 41001},
    [3] = {name = "Troll", amount = 10, missionStorage = 43001, storage = 41002}
}

function onKill(creature, target)
    if isPlayer(creature) and isMonster(target) then
        for i = 1, #missions do
            if target:getName() == missions[i].name then
                if creature:getStorageValue(missions[i].missionStorage) == 1 then
                    if creature:getStorageValue(missions[i].storage) < missions[i].amount then
                        creature:setStorageValue(missions[i].storage, creature:getStorageValue(missions[i].storage) + 1)
                        creature:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You have killed "..creature:getStorageValue(missions[i].storage).."/"..missions[i].amount..") "..missions[i].name.."('s)")
                    end
                end
            end
        end
    end
    return true
end

NPC file
Code:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

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

npcHandler:addModule(FocusModule:new())

local npcMissions = {
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    [1] = {name = "Rat Killer", -- Kill monsters only
        arrayName = {"Rat", "rat", "Rats", "rats", "Pest", "pest", "Pests", "pests", "rat killer", "Rat killer", "Rat Killer"},
        storageMission = 43000, -- Mission storage should be unique even in different NPC files.
        storageRequired = nil, -- Use this to require different tasks to be done complete before this task can be started.
        messageTaskInfo = "I need you to kill 10 rats and 10 cave rats.", -- This message is said to the player when he starts the task.
        messageTaskComplete = "Thank you! Those pests have ruined my store. unfortunately they will be back. The rats aren't the main {problem}", -- This message is said to the player when he finishs the task.
        windowMsg = "Kill rats in the basement.", -- This text is shown under the title of the modal window
        monsters = { -- Monster task
            [1] = {name = "Rat", amount = 10, storage = 41000}, -- Monster storages should be unique even in different NPC files.
            [2] = {name = "Cave Rat", amount = 10, storage = 41001}
        },
        --Rewards--
        exp = 1000, -- Exp given to the player for completing the task.
        rewardItems = { -- Items given to the player for completing the task.
            [1] = {itemid = 2390, amount = 1}
        },
        setStorage = nil -- Use this to set any storages you want to when the player completes the task excluding storageNpc and storageMission
    },
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    [2] = {name = "Troll Hunter",
        arrayName = {"troll hunter", "Troll Hunter", "Troll", "troll", "Trolls", "trolls"},
        storageMission = 43001,
        storageRequired = {43000},
        messageTaskInfo = "I need you to kill 20 trolls.",
        messageTaskComplete = "You are truley a legend. There is one more thing I need. Could you {help} me one more time?",
        windowMsg = "Kill trolls in the forst to the east. Also, collect x items",
        monsters = {
            [1] = {name = "Troll", amount = 20, storage = 41002},
        },
        collectItems = { -- Collect Items task
            [1] = {itemid = 1111, amount = 1}
        },
        --Rewards--
        exp = 5000,
        rewardItems = {
            [1] = {itemid = 2390, amount = 1}
        },
        setStorage = {
            [1] = {41532, 1}
        }
    },
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    [3] = {name = "The Collector", -- Collect Items only
        arrayName = {"collector", "Collector", "collect", "Collect", "cheese", "Cheese"},
        storageMission = 43003,
        storageRequired = {43001, 43002},
        messageTaskInfo = "I need you to collect 10 cheese.",
        messageTaskComplete = "You are truley a legend. I do not need anymore help.",
        windowMsg = "Collect x items",
        collectItems = { -- Collect Items task
            [1] = {itemid = 1111, amount = 1}
        },
        --Rewards--
        exp = 5000,
        rewardItems = {
            [1] = {itemid = 2390, amount = 1}
        },
        setStorage = nil
    }
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
}

local npcStory = { -- This story is told when the player first talks to the npc.
    [1] = "Not now adventurer. I have to deal with these pests.",
    [2] = "Honey! Get my broom, these things are everywhere. They aren't even scared of me!?",
    [3] = "If this continues we will have to close down our business!",
    [4] = "Please god send us some {help}!"
}

local MESSAGES_GREET = { -- Messages are based on the npcStorage for the player. This table handles all greeting interaction between the npc and player.
  --Storage / message
  -- The player gets his storage for the npc set as soon as he talks to the npc
  -- The players stoarge is set to 0. This table is accessed by MESSAGES[player:getStorageValue(npcStorage) - 1]
  -- Everytime a player accepts and completes one of the tasks/missions his npcStorage is increased by 1. That is how the code keeps track of how the npc should respond to the player.
    [1] = "Hello again |PLAYERNAME|. Do you want to {help} me yet?",
    [2] = "I am glad you decided to help. Are those {rats} giving you a problem?",
    [3] = "Thanks for killing those rats. I have another {task} I need {help} with.",
    [4] = "The trolls are powerful. Be sure to take strong gear with you.",
    [5] = "Thank you for all your help."
}

local MESSAGES_GOODBYE = { -- This works the same as MESSAGES_GREET. Depending on how many tasks the player has done for the npc. The npc will say different things when he says goodbye to the player.
    [1] = "Thanks for nothing |PLAYERNAME|.",
    [2] = "Thank you for your help. Goodbye.",
    [3] = "You have helped so much. I will be sure to tell other of you."
}

local arrayGreetings = {"hi", "Hi", "hello", "Hello", "hey", "Hey", "oi", "Oi", "hola", "Hola"}
local arrayFarewell = {"bye", "Bye", "goodbye", "Goodbye", "good-bye", "Good-Bye", "Good-bye", "cya", "adios", "Adios"}

local messageHearStoryAgain = "story"
local messageCheckTasks = {"help", "Help", "task", "Task", "tasks", "Tasks"}
local messageShowTasks = "Here is what I need help with."

local messageCompletedAllTasks = "Thank you for all you have done. I dont need anymore help."
local taskWindowTitle = "Title of Modal Window"
local taskWindowText = "Tasks"

local npcStorage = 45000

function onCreatureSay(cid, type, msg)
    local player = Player(cid)
    local playerGreetMessage = MESSAGES_GREET[player:getStorageValue(npcStorage)]
    local playerGoodbyeMessage = MESSAGES_GOODBYE[player:getStorageValue(npcStorage)]

    if isInArray(arrayGreetings, msg) and not npcHandler:isFocused(cid) and player:getStorageValue(npcStorage) == -1 then
        npcHandler:addFocus(cid)
        npcHandler:say(npcStory, player:getId(), false, true, 4000)
        player:setStorageValue(npcStorage, 1)

    elseif isInArray(arrayGreetings, msg) and not npcHandler:isFocused(cid) then
        npcHandler:addFocus(cid)
        if string.find(playerGreetMessage, "|PLAYERNAME|") then
            local newMsg = string.gsub(playerGreetMessage, "|PLAYERNAME|", player:getName())
            selfSay(newMsg, cid)
        else
            selfSay(playerGreetMessage, cid)
        end
    
    elseif isInArray(arrayFarewell, msg) and npcHandler:isFocused(cid) then
        if string.find(playerGoodbyeMessage, "|PLAYERNAME|") then
            local newMsg = string.gsub(playerGoodbyeMessage, "|PLAYERNAME|", player:getName())
            selfSay(newMsg, cid)
        else
            selfSay(playerGoodbyeMessage, cid)
        end
        player:setStorageValue(npcStorage, -1)
        npcHandler:releaseFocus(cid)
    
    elseif isInArray(messageCheckTasks, msg) and npcHandler:isFocused(cid) then
        local text = messageShowTasks
        local window = ModalWindow(0x10, taskWindowTitle, taskWindowText)
        local hasMissions = false
        for i = 1, #npcMissions do
            if player:getStorageValue(npcMissions[i].storageMission) < 2 then
                if npcMissions[i].storageRequired then
                local showTask = true
                    for x = 1, #npcMissions[i].storageRequired do
                        if player:getStorageValue(npcMissions[i].storageRequired[x]) ~= 2 then
                            showTask = false
                            break
                        end
                    end
                
                    if showTask then
                        window:addChoice(i, npcMissions[i].name)
                        hasMissions = true
                    end
                else
                    window:addChoice(i, npcMissions[i].name)
                    hasMissions = true
                end
            end
        end
    
        if hasMissions then
            window:addButton(0x00, "Exit")
            window:addButton(0x01, "Select")
            window:setDefaultEnterButton(0x01)
            window:sendToPlayer(player)
            return true
        else
            selfSay(messageCompletedAllTasks, cid)
            return true
        end
    end
return true
end

I have added everything as in this quote from you
I added the 2 scripts into creaturescripts\scripts and put the 2 lines into .xml

also I have taken NPC script from you which is working untill:

18:12 Jester: Hello again Gamemaster. Do you want to help me yet?

When I write 'help', following error appears in console

Lua Script Error: [Npc interface]
data/npc/scripts/test.lua:onCreatureSay
data/npc/scripts/test.lua:153: attempt to call global 'ModalWindow' (a nil value)
stack traceback:
[C]: in function 'ModalWindow'
data/npc/scripts/test.lua:153: in function <data/npc/scripts/test.lua:122>

errors when I run the server:

[Error - CreatureEvent::configureEvent] Invalid type for creature event: TaskSystemWindow
[Warning - BaseEvents::loadFromXml] Failed to configure event

I am using TFS 1.3 from Nekiro 8.6 downgrade!
I saw that you're saying it's working on 1.3. That's why I was confused why it didnt work for me :S
 
Tested Modal Windows conversion on TFS 1.3+, npc responds to hi, task, loads modal window, with Rat Killer, but after that you can't select anything. Also he does not lose focus on the player until you say bye.
1591100729963.png
to clarify, upon hitting "Select" the window disappears, same as with Exit.
 
Tested Modal Windows conversion on TFS 1.3+, npc responds to hi, task, loads modal window, with Rat Killer, but after that you can't select anything. Also he does not lose focus on the player until you say bye.
View attachment 46241
to clarify, upon hitting "Select" the window disappears, same as with Exit.
Same problem
 
I'll try to take a look at it if I get time, honestly forgot about it
 
Converter I tried for the Nostalrius 7.7 tfs 1.2 server still without success. Does anyone give a light?
 
Remember modal windows doesn't exist until 9.6+ i believe
 
with modal windows i have a problem, if i push Select window gone.
with no modal windows, rats are not counted.
 
I tested it on TFS 1.3.

Some bugs:
If u don't say "Bye" to npc he is always in talk with you everywhere,
I finish Rats task, if i was trying to start Troll task it take me back co Rats task.

I stumbled upon an answer for this. I've been looking for a long time now and finally got it to work.

Replace this function in npchandler.lua:

C++:
function NpcHandler:isInRange(cid)
        local distance = getDistanceBetween(getCreaturePosition(getNpcCid()), getCreaturePosition(cid))
        if(distance == -1) then
            return false
        end

        return (distance <= self.talkRadius)
    end

and make sure that this isn't commented out in the NPC file:

LUA:
function onThink()                          npcHandler:onThink()                        end
 
I stumbled upon an answer for this. I've been looking for a long time now and finally got it to work.

Replace this function in npchandler.lua:

C++:
function NpcHandler:isInRange(cid)
        local distance = getDistanceBetween(getCreaturePosition(getNpcCid()), getCreaturePosition(cid))
        if(distance == -1) then
            return false
        end

        return (distance <= self.talkRadius)
    end

and make sure that this isn't commented out in the NPC file:

LUA:
function onThink()                          npcHandler:onThink()                        end
1628983309614.png

after changing the function in npchandler all npcs stopped working. I use tfs 1.3 in RevScript OTServerBr server, can you help me?
Below is the current code.

LUA:
function NpcHandler:isInRange(cid)
        local distance = Player(cid) ~= nil and getDistanceTo(cid) or -1
        if distance == -1 then
            return false
        end
        return distance <= self.talkRadius
    end
 
Hi, finished the first rat task, but cant start the troll task, the second one.

Getting this error

Lua Script Error: [Npc interface]
data/npc/scripts/tasker.lua: onCreatureSay
data/npc/scripts/tasker.lua:136: bad argument #1 to 'find' (string expected, got nil)
stack traceback:
[C]: at 0x7ff7f7425940
[C]: in function 'find'
data/npc/scripts/tasker.lua:136: in function <data/npc/scripts/tasker.lua:116>



Tested on TFS 1.4, not the modal window version.

Also the npc does not respond saying "bye" or something when you get far, seems like once you say hi, the conversation continues forever no matter how far you are.
 
This should fix the npc focus problem

LUA:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

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

function onCreatureDisappear(cid)
    if npcHandler:hasFocus(cid) then
        npcHandler:releaseFocus(cid)
    end
end


npcHandler:addModule(FocusModule:new())

local npcMissions = {
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    [1] = {name = "Rat Killer", -- Kill monsters only
        arrayName = {"Rat", "rat", "Rats", "rats", "Pest", "pest", "Pests", "pests", "rat killer", "Rat killer", "Rat Killer"},
        storageMission = 43000, -- Mission storage should be unique even in different NPC files.
        storageRequired = nil, -- Use this to require different tasks to be done complete before this task can be started.
        messageTaskInfo = "I need you to kill 10 rats and 10 cave rats.", -- This message is said to the player when he starts the task.
        messageTaskComplete = "Thank you! Those pests have ruined my store. unfortunately they will be back. The rats aren't the main {problem}", -- This message is said to the player when he finishs the task.
        windowMsg = "Kill rats in the basement.", -- This text is shown under the title of the modal window
        monsters = { -- Monster task
            [1] = {name = "Rat", amount = 10, storage = 41000}, -- Monster storages should be unique even in different NPC files.
            [2] = {name = "Cave Rat", amount = 10, storage = 41001}
        },
        --Rewards--
        exp = 1000, -- Exp given to the player for completing the task.
        rewardItems = { -- Items given to the player for completing the task.
            [1] = {itemid = 2390, amount = 1}
        },
        setStorage = nil -- Use this to set any storages you want to when the player completes the task excluding storageNpc and storageMission
    },
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    [2] = {name = "Troll Hunter",
        arrayName = {"troll hunter", "Troll Hunter", "Troll", "troll", "Trolls", "trolls"},
        storageMission = 43001,
        storageRequired = {43000},
        messageTaskInfo = "I need you to kill 20 trolls.",
        messageTaskComplete = "You are truley a legend. There is one more thing I need. Could you {help} me one more time?",
        windowMsg = "Kill trolls in the forst to the east. Also, collect x items",
        monsters = {
            [1] = {name = "Troll", amount = 20, storage = 41002},
        },
        collectItems = { -- Collect Items task
            [1] = {itemid = 1111, amount = 1}
        },
        --Rewards--
        exp = 5000,
        rewardItems = {
            [1] = {itemid = 2390, amount = 1}
        },
        setStorage = {
            [1] = {41532, 1}
        }
    },
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    [3] = {name = "The Collector", -- Collect Items only
        arrayName = {"collector", "Collector", "collect", "Collect", "cheese", "Cheese"},
        storageMission = 43003,
        storageRequired = {43001, 43002},
        messageTaskInfo = "I need you to collect 10 cheese.",
        messageTaskComplete = "You are truley a legend. I do not need anymore help.",
        windowMsg = "Collect x items",
        collectItems = { -- Collect Items task
            [1] = {itemid = 1111, amount = 1}
        },
        --Rewards--
        exp = 5000,
        rewardItems = {
            [1] = {itemid = 2390, amount = 1}
        },
        setStorage = nil
    }
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
}

local npcStory = { -- This story is told when the player first talks to the npc.
    [1] = "Not now adventurer. I have to deal with these pests.",
    [2] = "Honey! Get my broom, these things are everywhere. They aren't even scared of me!?",
    [3] = "If this continues we will have to close down our business!",
    [4] = "Please god send us some {help}!"
}

local MESSAGES_GREET = { -- Messages are based on the npcStorage for the player. This table handles all greeting interaction between the npc and player.
  --Storage / message
  -- The player gets his storage for the npc set as soon as he talks to the npc
  -- The players stoarge is set to 0. This table is accessed by MESSAGES[player:getStorageValue(npcStorage) - 1]
  -- Everytime a player accepts and completes one of the tasks/missions his npcStorage is increased by 1. That is how the code keeps track of how the npc should respond to the player.
    [1] = "Hello again |PLAYERNAME|. Do you want to {help} me yet?",
    [2] = "I am glad you decided to help. Are those {rats} giving you a problem?",
    [3] = "Thanks for killing those rats. I have another {task} I need {help} with.",
    [4] = "The trolls are powerful. Be sure to take strong gear with you.",
    [5] = "Thank you for all your help."
}

local MESSAGES_GOODBYE = { -- This works the same as MESSAGES_GREET. Depending on how many tasks the player has done for the npc. The npc will say different things when he says goodbye to the player.
    [1] = "Thanks for nothing |PLAYERNAME|.",
    [2] = "Thank you for your help. Goodbye.",
    [3] = "You have helped so much. I will be sure to tell other of you."
}

local arrayGreetings = {"hi", "Hi", "hello", "Hello", "hey", "Hey", "oi", "Oi", "hola", "Hola"}
local arrayFarewell = {"bye", "Bye", "goodbye", "Goodbye", "good-bye", "Good-Bye", "Good-bye", "cya", "adios", "Adios"}

local messageHearStoryAgain = "story"
local messageCheckTasks = {"help", "Help", "task", "Task", "tasks", "Tasks"}
local messageShowTasks = "Here is what I need help with."

local messageCompletedAllTasks = "Thank you for all you have done. I dont need anymore help."
local taskWindowTitle = "Title of Modal Window"
local taskWindowText = "Tasks"

local npcStorage = 45000

function onCreatureSay(cid, type, msg)
    local player = Player(cid)
    local playerGreetMessage = MESSAGES_GREET[player:getStorageValue(npcStorage)]
    local playerGoodbyeMessage = MESSAGES_GOODBYE[player:getStorageValue(npcStorage)]
 
    if isInArray(arrayGreetings, msg) and not npcHandler:isFocused(cid) and player:getStorageValue(npcStorage) == -1 then
        npcHandler:addFocus(cid)
        npcHandler:say(npcStory, player:getId(), false, true, 4000)
        player:setStorageValue(npcStorage, 1)
 
    elseif isInArray(arrayGreetings, msg) and not npcHandler:isFocused(cid) then
        npcHandler:addFocus(cid)
        if string.find(playerGreetMessage, "|PLAYERNAME|") then
            local newMsg = string.gsub(playerGreetMessage, "|PLAYERNAME|", player:getName())
            selfSay(newMsg, cid)
        else
            selfSay(playerGreetMessage, cid)
        end
   
    elseif isInArray(arrayFarewell, msg) and npcHandler:isFocused(cid) then
        if string.find(playerGoodbyeMessage, "|PLAYERNAME|") then
            local newMsg = string.gsub(playerGoodbyeMessage, "|PLAYERNAME|", player:getName())
            selfSay(newMsg, cid)
        else
            selfSay(playerGoodbyeMessage, cid)
        end
        player:setStorageValue(npcStorage, -1)
        npcHandler:releaseFocus(cid)
   
    elseif isInArray(messageCheckTasks, msg) and npcHandler:isFocused(cid) then
        local text = messageShowTasks
        local window = ModalWindow(0x10, taskWindowTitle, taskWindowText)
        local hasMissions = false
        for i = 1, #npcMissions do
            if player:getStorageValue(npcMissions[i].storageMission) < 2 then
                if npcMissions[i].storageRequired then
                local showTask = true
                    for x = 1, #npcMissions[i].storageRequired do
                        if player:getStorageValue(npcMissions[i].storageRequired[x]) ~= 2 then
                            showTask = false
                            break
                        end
                    end
               
                    if showTask then
                        window:addChoice(i, npcMissions[i].name)
                        hasMissions = true
                    end
                else
                    window:addChoice(i, npcMissions[i].name)
                    hasMissions = true
                end
            end
        end
   
        if hasMissions then
            window:addButton(0x00, "Exit")
            window:addButton(0x01, "Select")
            window:setDefaultEnterButton(0x01)
            window:sendToPlayer(player)
            return true
        else
            selfSay(messageCompletedAllTasks, cid)
            return true
        end
      
    elseif msg == "bye" then
        selfSay("Good-bye", cid)
        npcHandler:releaseFocus(cid)
    end
return true
end
Post automatically merged:

TaskSystemKill.lua replace with this and it should fix it.

LUA:
local missions = { -- Use missionStorage to link the monsters to each mission. It is set up this way so multiple missions can have the same monsters.
    [1] = {name = "Rat", amount = 10, missionStorage = 43000, storage = 41000},
    [2] = {name = "Cave Rat", amount = 10, missionStorage = 43000, storage = 41001},
    [3] = {name = "Troll", amount = 10, missionStorage = 43001, storage = 41002}
}

function onKill(creature, target)
    local player = Player(creature)
   
    if not player then return true end

    for i = 1, #missions do
        if target:getName() == missions[i].name then
            if player:getStorageValue(missions[i].missionStorage) == 1 then
            local mStorage = player:getStorageValue(missions[i].storage)
                if mStorage == -1 then
                    player:setStorageValue(missions[i].storage, 1)
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You have killed "..player:getStorageValue(missions[i].storage).."/"..missions[i].amount..") "..missions[i].name.."('s)")
                elseif mStorage < missions[i].amount then
                    player:setStorageValue(mStorage, mStorage + 1)
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You have killed "..player:getStorageValue(missions[i].storage).."/"..missions[i].amount..") "..missions[i].name.."('s)")
                end
            end
        end
    end
    return true
end
 
Last edited:
This should fix the npc focus problem

LUA:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

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

function onCreatureDisappear(cid)
    if npcHandler:hasFocus(cid) then
        npcHandler:releaseFocus(cid)
    end
end


npcHandler:addModule(FocusModule:new())

local npcMissions = {
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    [1] = {name = "Rat Killer", -- Kill monsters only
        arrayName = {"Rat", "rat", "Rats", "rats", "Pest", "pest", "Pests", "pests", "rat killer", "Rat killer", "Rat Killer"},
        storageMission = 43000, -- Mission storage should be unique even in different NPC files.
        storageRequired = nil, -- Use this to require different tasks to be done complete before this task can be started.
        messageTaskInfo = "I need you to kill 10 rats and 10 cave rats.", -- This message is said to the player when he starts the task.
        messageTaskComplete = "Thank you! Those pests have ruined my store. unfortunately they will be back. The rats aren't the main {problem}", -- This message is said to the player when he finishs the task.
        windowMsg = "Kill rats in the basement.", -- This text is shown under the title of the modal window
        monsters = { -- Monster task
            [1] = {name = "Rat", amount = 10, storage = 41000}, -- Monster storages should be unique even in different NPC files.
            [2] = {name = "Cave Rat", amount = 10, storage = 41001}
        },
        --Rewards--
        exp = 1000, -- Exp given to the player for completing the task.
        rewardItems = { -- Items given to the player for completing the task.
            [1] = {itemid = 2390, amount = 1}
        },
        setStorage = nil -- Use this to set any storages you want to when the player completes the task excluding storageNpc and storageMission
    },
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    [2] = {name = "Troll Hunter",
        arrayName = {"troll hunter", "Troll Hunter", "Troll", "troll", "Trolls", "trolls"},
        storageMission = 43001,
        storageRequired = {43000},
        messageTaskInfo = "I need you to kill 20 trolls.",
        messageTaskComplete = "You are truley a legend. There is one more thing I need. Could you {help} me one more time?",
        windowMsg = "Kill trolls in the forst to the east. Also, collect x items",
        monsters = {
            [1] = {name = "Troll", amount = 20, storage = 41002},
        },
        collectItems = { -- Collect Items task
            [1] = {itemid = 1111, amount = 1}
        },
        --Rewards--
        exp = 5000,
        rewardItems = {
            [1] = {itemid = 2390, amount = 1}
        },
        setStorage = {
            [1] = {41532, 1}
        }
    },
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    [3] = {name = "The Collector", -- Collect Items only
        arrayName = {"collector", "Collector", "collect", "Collect", "cheese", "Cheese"},
        storageMission = 43003,
        storageRequired = {43001, 43002},
        messageTaskInfo = "I need you to collect 10 cheese.",
        messageTaskComplete = "You are truley a legend. I do not need anymore help.",
        windowMsg = "Collect x items",
        collectItems = { -- Collect Items task
            [1] = {itemid = 1111, amount = 1}
        },
        --Rewards--
        exp = 5000,
        rewardItems = {
            [1] = {itemid = 2390, amount = 1}
        },
        setStorage = nil
    }
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
}

local npcStory = { -- This story is told when the player first talks to the npc.
    [1] = "Not now adventurer. I have to deal with these pests.",
    [2] = "Honey! Get my broom, these things are everywhere. They aren't even scared of me!?",
    [3] = "If this continues we will have to close down our business!",
    [4] = "Please god send us some {help}!"
}

local MESSAGES_GREET = { -- Messages are based on the npcStorage for the player. This table handles all greeting interaction between the npc and player.
  --Storage / message
  -- The player gets his storage for the npc set as soon as he talks to the npc
  -- The players stoarge is set to 0. This table is accessed by MESSAGES[player:getStorageValue(npcStorage) - 1]
  -- Everytime a player accepts and completes one of the tasks/missions his npcStorage is increased by 1. That is how the code keeps track of how the npc should respond to the player.
    [1] = "Hello again |PLAYERNAME|. Do you want to {help} me yet?",
    [2] = "I am glad you decided to help. Are those {rats} giving you a problem?",
    [3] = "Thanks for killing those rats. I have another {task} I need {help} with.",
    [4] = "The trolls are powerful. Be sure to take strong gear with you.",
    [5] = "Thank you for all your help."
}

local MESSAGES_GOODBYE = { -- This works the same as MESSAGES_GREET. Depending on how many tasks the player has done for the npc. The npc will say different things when he says goodbye to the player.
    [1] = "Thanks for nothing |PLAYERNAME|.",
    [2] = "Thank you for your help. Goodbye.",
    [3] = "You have helped so much. I will be sure to tell other of you."
}

local arrayGreetings = {"hi", "Hi", "hello", "Hello", "hey", "Hey", "oi", "Oi", "hola", "Hola"}
local arrayFarewell = {"bye", "Bye", "goodbye", "Goodbye", "good-bye", "Good-Bye", "Good-bye", "cya", "adios", "Adios"}

local messageHearStoryAgain = "story"
local messageCheckTasks = {"help", "Help", "task", "Task", "tasks", "Tasks"}
local messageShowTasks = "Here is what I need help with."

local messageCompletedAllTasks = "Thank you for all you have done. I dont need anymore help."
local taskWindowTitle = "Title of Modal Window"
local taskWindowText = "Tasks"

local npcStorage = 45000

function onCreatureSay(cid, type, msg)
    local player = Player(cid)
    local playerGreetMessage = MESSAGES_GREET[player:getStorageValue(npcStorage)]
    local playerGoodbyeMessage = MESSAGES_GOODBYE[player:getStorageValue(npcStorage)]
 
    if isInArray(arrayGreetings, msg) and not npcHandler:isFocused(cid) and player:getStorageValue(npcStorage) == -1 then
        npcHandler:addFocus(cid)
        npcHandler:say(npcStory, player:getId(), false, true, 4000)
        player:setStorageValue(npcStorage, 1)
 
    elseif isInArray(arrayGreetings, msg) and not npcHandler:isFocused(cid) then
        npcHandler:addFocus(cid)
        if string.find(playerGreetMessage, "|PLAYERNAME|") then
            local newMsg = string.gsub(playerGreetMessage, "|PLAYERNAME|", player:getName())
            selfSay(newMsg, cid)
        else
            selfSay(playerGreetMessage, cid)
        end
 
    elseif isInArray(arrayFarewell, msg) and npcHandler:isFocused(cid) then
        if string.find(playerGoodbyeMessage, "|PLAYERNAME|") then
            local newMsg = string.gsub(playerGoodbyeMessage, "|PLAYERNAME|", player:getName())
            selfSay(newMsg, cid)
        else
            selfSay(playerGoodbyeMessage, cid)
        end
        player:setStorageValue(npcStorage, -1)
        npcHandler:releaseFocus(cid)
 
    elseif isInArray(messageCheckTasks, msg) and npcHandler:isFocused(cid) then
        local text = messageShowTasks
        local window = ModalWindow(0x10, taskWindowTitle, taskWindowText)
        local hasMissions = false
        for i = 1, #npcMissions do
            if player:getStorageValue(npcMissions[i].storageMission) < 2 then
                if npcMissions[i].storageRequired then
                local showTask = true
                    for x = 1, #npcMissions[i].storageRequired do
                        if player:getStorageValue(npcMissions[i].storageRequired[x]) ~= 2 then
                            showTask = false
                            break
                        end
                    end
            
                    if showTask then
                        window:addChoice(i, npcMissions[i].name)
                        hasMissions = true
                    end
                else
                    window:addChoice(i, npcMissions[i].name)
                    hasMissions = true
                end
            end
        end
 
        if hasMissions then
            window:addButton(0x00, "Exit")
            window:addButton(0x01, "Select")
            window:setDefaultEnterButton(0x01)
            window:sendToPlayer(player)
            return true
        else
            selfSay(messageCompletedAllTasks, cid)
            return true
        end
   
    elseif msg == "bye" then
        selfSay("Good-bye", cid)
        npcHandler:releaseFocus(cid)
    end
return true
end
Post automatically merged:

TaskSystemKill.lua replace with this and it should fix it.

LUA:
local missions = { -- Use missionStorage to link the monsters to each mission. It is set up this way so multiple missions can have the same monsters.
    [1] = {name = "Rat", amount = 10, missionStorage = 43000, storage = 41000},
    [2] = {name = "Cave Rat", amount = 10, missionStorage = 43000, storage = 41001},
    [3] = {name = "Troll", amount = 10, missionStorage = 43001, storage = 41002}
}

function onKill(creature, target)
    local player = Player(creature)
 
    if not player then return true end

    for i = 1, #missions do
        if target:getName() == missions[i].name then
            if player:getStorageValue(missions[i].missionStorage) == 1 then
            local mStorage = player:getStorageValue(missions[i].storage)
                if mStorage == -1 then
                    player:setStorageValue(missions[i].storage, 1)
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You have killed "..player:getStorageValue(missions[i].storage).."/"..missions[i].amount..") "..missions[i].name.."('s)")
                elseif mStorage < missions[i].amount then
                    player:setStorageValue(mStorage, mStorage + 1)
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You have killed "..player:getStorageValue(missions[i].storage).."/"..missions[i].amount..") "..missions[i].name.."('s)")
                end
            end
        end
    end
    return true
end
Code:
Lua Script Error: [Npc interface]
data/npc/scripts/indra.lua:onCreatureDisappear
data/npc/scripts/indra.lua:12: attempt to call method 'hasFocus' (a nil value)
stack traceback:
        [C]: in function 'hasFocus'
        data/npc/scripts/indra.lua:12: in function <data/npc/scripts/indra.lua:11>
when i logout i receive this in my console
Post automatically merged:

This should fix the npc focus problem

LUA:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

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

function onCreatureDisappear(cid)
    if npcHandler:hasFocus(cid) then
        npcHandler:releaseFocus(cid)
    end
end


npcHandler:addModule(FocusModule:new())

local npcMissions = {
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    [1] = {name = "Rat Killer", -- Kill monsters only
        arrayName = {"Rat", "rat", "Rats", "rats", "Pest", "pest", "Pests", "pests", "rat killer", "Rat killer", "Rat Killer"},
        storageMission = 43000, -- Mission storage should be unique even in different NPC files.
        storageRequired = nil, -- Use this to require different tasks to be done complete before this task can be started.
        messageTaskInfo = "I need you to kill 10 rats and 10 cave rats.", -- This message is said to the player when he starts the task.
        messageTaskComplete = "Thank you! Those pests have ruined my store. unfortunately they will be back. The rats aren't the main {problem}", -- This message is said to the player when he finishs the task.
        windowMsg = "Kill rats in the basement.", -- This text is shown under the title of the modal window
        monsters = { -- Monster task
            [1] = {name = "Rat", amount = 10, storage = 41000}, -- Monster storages should be unique even in different NPC files.
            [2] = {name = "Cave Rat", amount = 10, storage = 41001}
        },
        --Rewards--
        exp = 1000, -- Exp given to the player for completing the task.
        rewardItems = { -- Items given to the player for completing the task.
            [1] = {itemid = 2390, amount = 1}
        },
        setStorage = nil -- Use this to set any storages you want to when the player completes the task excluding storageNpc and storageMission
    },
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    [2] = {name = "Troll Hunter",
        arrayName = {"troll hunter", "Troll Hunter", "Troll", "troll", "Trolls", "trolls"},
        storageMission = 43001,
        storageRequired = {43000},
        messageTaskInfo = "I need you to kill 20 trolls.",
        messageTaskComplete = "You are truley a legend. There is one more thing I need. Could you {help} me one more time?",
        windowMsg = "Kill trolls in the forst to the east. Also, collect x items",
        monsters = {
            [1] = {name = "Troll", amount = 20, storage = 41002},
        },
        collectItems = { -- Collect Items task
            [1] = {itemid = 1111, amount = 1}
        },
        --Rewards--
        exp = 5000,
        rewardItems = {
            [1] = {itemid = 2390, amount = 1}
        },
        setStorage = {
            [1] = {41532, 1}
        }
    },
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    [3] = {name = "The Collector", -- Collect Items only
        arrayName = {"collector", "Collector", "collect", "Collect", "cheese", "Cheese"},
        storageMission = 43003,
        storageRequired = {43001, 43002},
        messageTaskInfo = "I need you to collect 10 cheese.",
        messageTaskComplete = "You are truley a legend. I do not need anymore help.",
        windowMsg = "Collect x items",
        collectItems = { -- Collect Items task
            [1] = {itemid = 1111, amount = 1}
        },
        --Rewards--
        exp = 5000,
        rewardItems = {
            [1] = {itemid = 2390, amount = 1}
        },
        setStorage = nil
    }
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
    --------------------------------------------------------------------------------------------------------------------------------
}

local npcStory = { -- This story is told when the player first talks to the npc.
    [1] = "Not now adventurer. I have to deal with these pests.",
    [2] = "Honey! Get my broom, these things are everywhere. They aren't even scared of me!?",
    [3] = "If this continues we will have to close down our business!",
    [4] = "Please god send us some {help}!"
}

local MESSAGES_GREET = { -- Messages are based on the npcStorage for the player. This table handles all greeting interaction between the npc and player.
  --Storage / message
  -- The player gets his storage for the npc set as soon as he talks to the npc
  -- The players stoarge is set to 0. This table is accessed by MESSAGES[player:getStorageValue(npcStorage) - 1]
  -- Everytime a player accepts and completes one of the tasks/missions his npcStorage is increased by 1. That is how the code keeps track of how the npc should respond to the player.
    [1] = "Hello again |PLAYERNAME|. Do you want to {help} me yet?",
    [2] = "I am glad you decided to help. Are those {rats} giving you a problem?",
    [3] = "Thanks for killing those rats. I have another {task} I need {help} with.",
    [4] = "The trolls are powerful. Be sure to take strong gear with you.",
    [5] = "Thank you for all your help."
}

local MESSAGES_GOODBYE = { -- This works the same as MESSAGES_GREET. Depending on how many tasks the player has done for the npc. The npc will say different things when he says goodbye to the player.
    [1] = "Thanks for nothing |PLAYERNAME|.",
    [2] = "Thank you for your help. Goodbye.",
    [3] = "You have helped so much. I will be sure to tell other of you."
}

local arrayGreetings = {"hi", "Hi", "hello", "Hello", "hey", "Hey", "oi", "Oi", "hola", "Hola"}
local arrayFarewell = {"bye", "Bye", "goodbye", "Goodbye", "good-bye", "Good-Bye", "Good-bye", "cya", "adios", "Adios"}

local messageHearStoryAgain = "story"
local messageCheckTasks = {"help", "Help", "task", "Task", "tasks", "Tasks"}
local messageShowTasks = "Here is what I need help with."

local messageCompletedAllTasks = "Thank you for all you have done. I dont need anymore help."
local taskWindowTitle = "Title of Modal Window"
local taskWindowText = "Tasks"

local npcStorage = 45000

function onCreatureSay(cid, type, msg)
    local player = Player(cid)
    local playerGreetMessage = MESSAGES_GREET[player:getStorageValue(npcStorage)]
    local playerGoodbyeMessage = MESSAGES_GOODBYE[player:getStorageValue(npcStorage)]
 
    if isInArray(arrayGreetings, msg) and not npcHandler:isFocused(cid) and player:getStorageValue(npcStorage) == -1 then
        npcHandler:addFocus(cid)
        npcHandler:say(npcStory, player:getId(), false, true, 4000)
        player:setStorageValue(npcStorage, 1)
 
    elseif isInArray(arrayGreetings, msg) and not npcHandler:isFocused(cid) then
        npcHandler:addFocus(cid)
        if string.find(playerGreetMessage, "|PLAYERNAME|") then
            local newMsg = string.gsub(playerGreetMessage, "|PLAYERNAME|", player:getName())
            selfSay(newMsg, cid)
        else
            selfSay(playerGreetMessage, cid)
        end
 
    elseif isInArray(arrayFarewell, msg) and npcHandler:isFocused(cid) then
        if string.find(playerGoodbyeMessage, "|PLAYERNAME|") then
            local newMsg = string.gsub(playerGoodbyeMessage, "|PLAYERNAME|", player:getName())
            selfSay(newMsg, cid)
        else
            selfSay(playerGoodbyeMessage, cid)
        end
        player:setStorageValue(npcStorage, -1)
        npcHandler:releaseFocus(cid)
 
    elseif isInArray(messageCheckTasks, msg) and npcHandler:isFocused(cid) then
        local text = messageShowTasks
        local window = ModalWindow(0x10, taskWindowTitle, taskWindowText)
        local hasMissions = false
        for i = 1, #npcMissions do
            if player:getStorageValue(npcMissions[i].storageMission) < 2 then
                if npcMissions[i].storageRequired then
                local showTask = true
                    for x = 1, #npcMissions[i].storageRequired do
                        if player:getStorageValue(npcMissions[i].storageRequired[x]) ~= 2 then
                            showTask = false
                            break
                        end
                    end
            
                    if showTask then
                        window:addChoice(i, npcMissions[i].name)
                        hasMissions = true
                    end
                else
                    window:addChoice(i, npcMissions[i].name)
                    hasMissions = true
                end
            end
        end
 
        if hasMissions then
            window:addButton(0x00, "Exit")
            window:addButton(0x01, "Select")
            window:setDefaultEnterButton(0x01)
            window:sendToPlayer(player)
            return true
        else
            selfSay(messageCompletedAllTasks, cid)
            return true
        end
   
    elseif msg == "bye" then
        selfSay("Good-bye", cid)
        npcHandler:releaseFocus(cid)
    end
return true
end
Post automatically merged:

TaskSystemKill.lua replace with this and it should fix it.

LUA:
local missions = { -- Use missionStorage to link the monsters to each mission. It is set up this way so multiple missions can have the same monsters.
    [1] = {name = "Rat", amount = 10, missionStorage = 43000, storage = 41000},
    [2] = {name = "Cave Rat", amount = 10, missionStorage = 43000, storage = 41001},
    [3] = {name = "Troll", amount = 10, missionStorage = 43001, storage = 41002}
}

function onKill(creature, target)
    local player = Player(creature)
 
    if not player then return true end

    for i = 1, #missions do
        if target:getName() == missions[i].name then
            if player:getStorageValue(missions[i].missionStorage) == 1 then
            local mStorage = player:getStorageValue(missions[i].storage)
                if mStorage == -1 then
                    player:setStorageValue(missions[i].storage, 1)
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You have killed "..player:getStorageValue(missions[i].storage).."/"..missions[i].amount..") "..missions[i].name.."('s)")
                elseif mStorage < missions[i].amount then
                    player:setStorageValue(mStorage, mStorage + 1)
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "You have killed "..player:getStorageValue(missions[i].storage).."/"..missions[i].amount..") "..missions[i].name.."('s)")
                end
            end
        end
    end
    return true
end
Also it doesn't count what I'm actually killing also i double checked that i added those in my login.lua
LUA:
    player:registerEvent("TaskSystemWindow")
    player:registerEvent("TaskSystemKill")
1652665772872.png
 
Last edited:
Code:
Lua Script Error: [Npc interface]
data/npc/scripts/indra.lua:onCreatureDisappear
data/npc/scripts/indra.lua:12: attempt to call method 'hasFocus' (a nil value)
stack traceback:
        [C]: in function 'hasFocus'
        data/npc/scripts/indra.lua:12: in function <data/npc/scripts/indra.lua:11>
when i logout i receive this in my console
Post automatically merged:


Also it doesn't count what I'm actually killing also i double checked that i added those in my login.lua
LUA:
    player:registerEvent("TaskSystemWindow")
    player:registerEvent("TaskSystemKill")

Change hasFocus to isFocused

You must be setting up the configs wrong or something. Send me a PM of your exact set up. Unless you just copy pasted and tested.
 
Last edited:
Back
Top