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

How to make NPC task master in TFS 1.0?

whitevo

Feeling good, thats what I do.
Joined
Jan 2, 2015
Messages
3,452
Solutions
1
Reaction score
626
Location
Estonia
Trying to make a NPC what gives tasks, but i lot of script examples in OTland are confusing me.

BTW, this is working script below if someone wants to try it out

picture for file locations
2mw9vq.jpg

tasks.lua
Code:
local tasks =
{
["deer"] = {storage = 10100, killsRequired = 20},
["wolf"] = {storage = 10101, killsRequired = 20},
["boar"] = {storage = 10102, killsRequired = 20},
["bear"] = {storage = 10103, killsRequired = 20} 
}

function onKill(cid, target)
  local monster = tasks[getCreatureName(target):lower()]
  if isPlayer(target) or not monster or isSummon(target) then
  return true
  end

  if (getPlayerStorageValue(cid, monster.storage)-1) < monster.killsRequired and getPlayerStorageValue(cid, monster.storage) >= 1 then
  setPlayerStorageValue(cid, monster.storage, getPlayerStorageValue(cid, monster.storage) + 1)
  doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, 'Task message: '..(getPlayerStorageValue(cid, monster.storage)-1)..' of '..monster.killsRequired..' '..getCreatureName(target)..'s killed.')
  end
  if (getPlayerStorageValue(cid, monster.storage)-1) == monster.killsRequired then
  doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'Congratulations, you have killed '..(getPlayerStorageValue(cid, monster.storage)-1)..' '..getCreatureName(target)..'s and completed the '..getCreatureName(target)..'s mission.')
  setPlayerStorageValue(cid, monster.storage, 0)
  end
  return true
end

login.lua
Code:
function onLogin(cid)
   --#other stuff--
   player:registerEvent("PlayerDeath")
   player:registerEvent("tasks")
   return true
end
creaturescripts.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<creaturescripts>

   <!-- This was here before -->
   <event type="login" name="PlayerLogin" script="login.lua"/>
   <event type="death" name="PlayerDeath" script="playerdeath.lua"/>
   <event type="extendedopcode" name="ExtendedOpcode" script="extendedopcode.lua"/>
   <event type="kill" name="tasks" script="tasks.lua"/>
</creaturescripts>

Task Master.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<npc name="Task Master" script="tasks.lua" walkinterval="2000" speed="200" walkradius="4" floorchange="0" speechbubble="3">
    <health max="100" now="100"/>
    <look type="264" head="78" body="116" legs="95" feet="121" corpse="20339"/>
</npc>

boar.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<monster name="Boar" nameDescription="a boar" race="blood" experience="60" speed="230" manacost="465">
    <health now="3000" max="3000"/>
    <look type="380" corpse="13308"/>
    <targetchange interval="5000" chance="40"/>
    <event name="tasks"/>

... i cut out all the other stuff about monsters.. no need extra information what doesn't help.

</monster>

this tasks.lua is activated from NPC
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

local tasks =
{
["deer"] = {minL = 1, maxL = 3, killsRequired = 20},
["wolf"] = {minL = 2, maxL = 4, killsRequired = 20},
["boar"] = {minL = 2, maxL = 5, killsRequired = 20},
["bear"] = {minL = 2, maxL = 5, killsRequired = 20}
}


npcHandler.messages[MESSAGE_GREET] = "Hello, |PLAYERNAME| do you want a new {task} or {report} a finished one?"

function creatureSayCallback(cid, type, msg)
   if (not npcHandler:isFocused(cid)) then
   return false
   end

local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_PRIVATE and 0 or cid
local L = getPlayerLevel(cid)

--NPC OFFERS THESE TASKS IF MATCHED REQUIREMENTS
   if msgcontains(msg:lower(), 'task') then
     if L >= tasks["deer"].minL and L <= tasks["deer"].maxL then
       if getPlayerStorageValue(cid, 10100) < 1 then
         selfSay ("Say {deer} for task ", cid)
       end
     end
     if L >= tasks["wolf"].minL and L <= tasks["wolf"].maxL then
       if getPlayerStorageValue(cid, 10101)  < 1 then
         selfSay ("Say {wolf} for task", cid)
       end
     end
     if L >= tasks["boar"].minL and L <= tasks["boar"].maxL then
       if getPlayerStorageValue(cid, 10102) < 1 then
         selfSay ("Say {boar} for task", cid)
       end
     end
     if L >= tasks["bear"].minL and L <= tasks["bear"].maxL then
       if getPlayerStorageValue(cid, 10103) < 1 then
         selfSay ("Say {bear} for task", cid)
       end

     else selfSay ("NO MOAR TASKS!!", cid)
     end

   elseif msgcontains(msg:lower(), 'check') then
     selfSay (getPlayerStorageValue(cid, 10100), cid)
   elseif   msgcontains(msg:lower(), 'reset') then
     setPlayerStorageValue(cid, 10100, -1)
-- PLAYER CAN TAKE TASK IF REQUIREMENTS MATCH
   elseif msgcontains(msg, "deer") and L >= tasks["deer"].minL and L <= tasks["deer"].maxL and getPlayerStorageValue(cid, 10100) < 1 then
     setPlayerStorageValue(cid, 10100, 1)
     questAccepted = selfSay ("You accepted task to kill " .. tasks["deer"].killsRequired .. " deers", cid)

   elseif msgcontains(msg, "wolf") and L >= tasks["wolf"].minL and L <= tasks["wolf"].maxL and getPlayerStorageValue(cid, 10101) < 1 then
     setPlayerStorageValue(cid, 10101, 1)
     selfSay ("You accepted task to kill " .. tasks["wolf"].killsRequired .. " wolves", cid)

   elseif msgcontains(msg, "boar") and L >= tasks["boar"].minL and L <= tasks["boar"].maxL and getPlayerStorageValue(cid, 10102) < 1 then
     setPlayerStorageValue(cid, 10102, 1)
     selfSay ("You accepted task to kill " .. tasks["boar"].killsRequired .. " boars", cid)

   elseif msgcontains(msg, "bear") and L >= tasks["bear"].minL and L <= tasks["bear"].maxL and getPlayerStorageValue(cid, 10103) < 1 then
     setPlayerStorageValue(cid, 10103, 1)
     selfSay ("You accepted task to kill " .. tasks["bear"].killsRequired .. " bears", cid)

-- IF TASK TAKEN IT GIVES FEEDBACK OR REWARD
   elseif msgcontains(msg, "report") then
     -- deer task
     if getPlayerStorageValue(cid, 10100) == 0  then
       -- give Skill experience (no idea how)
       setPlayerStorageValue(cid, 10100, -1)
       selfSay("you completed task", cid)
     elseif getPlayerStorageValue(cid, 10100) > 0  then
       selfSay("You have killed " .. getPlayerStorageValue(cid, 10100)-1 .. " out of " .. tasks["deer"].killsRequired .. " deers", cid)
     end
     -- wolf task
     if getPlayerStorageValue(cid, 10101) == 0  then
       -- give Skill experience (no idea how)
       setPlayerStorageValue(cid, 10101, -1)
       selfSay("you completed task", cid)
     elseif getPlayerStorageValue(cid, 10101) > 0  then
       selfSay("You have killed " .. getPlayerStorageValue(cid, 10101)-1 .. " out of " .. tasks["wolf"].killsRequired .. " wolves", cid)
     end
     -- boar task
     if getPlayerStorageValue(cid, 10102) == 0  then
       -- give Skill experience (no idea how)
       setPlayerStorageValue(cid, 10102, -1)
       selfSay("you completed task", cid)
     elseif getPlayerStorageValue(cid, 10102) > 0  then
       selfSay("You have killed " .. getPlayerStorageValue(cid, 10102)-1 .. " out of " .. tasks["boar"].killsRequired .. " boars", cid)
     end
     -- bear task
     if getPlayerStorageValue(cid, 10103) == 0  then
       -- give Skill experience (no idea how)
       setPlayerStorageValue(cid, 10103, -1)
       selfSay("you completed task", cid)
     elseif getPlayerStorageValue(cid, 10103) > 0  then
       selfSay("You have killed " .. getPlayerStorageValue(cid, 10103)-1 .. " out of " .. tasks["bear"].killsRequired .. " bears", cid)
     end

   end
return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Last edited:
try putting the table underneath function onThink() npcHandler:eek:nThink() end and see if that works
Code:
local tasks =
{
["deer"] = {questStarted = 1510, questStorage = 65000, killsRequired = 20, raceName = "Deers"},
["wolf"] = {questStarted = 1511, questStorage = 65001, killsRequired = 20, raceName = "Wolves"},
["boar"] = {questStarted = 1512, questStorage = 65002, killsRequired = 20, raceName = "Boars"},
["bear"]= {questStarted = 1513, questStorage = 65003, killsRequired = 20, raceName = "Bears"}
}

Also change this
Code:
[above functions are altered to "fit" to TFS 1.0 , but maybe i shuld keep the orginal :eek: lines in there?]
to this
Code:
--[[above functions are altered to "fit" to TFS 1.0 , but maybe i shuld keep the orginal :eek: lines in there?]]

You can also change this
Code:
if msgcontains(msg, 'task') or msgcontains(msg, 'tasks') or msgcontains(msg, 'Task') or msgcontains(msg, 'Tasks') then
to this
Code:
if msgcontains(msg:lower(), 'task') then
because if they say tasks, task is within the msg

Also you can't reference an index of a table using a const that is not defined
Code:
tasks[wolf] -- wolf is seen as a const rather than an index of the table
should be
Code:
tasks["wolf"]

I am just going step by step because its better your understand how the script should work

This script needs a complete re-write, a+ for effort tho :)

figure it out yourself
 
Last edited by a moderator:
i updated all the changes you suggested for tasks.lua (red text is not in the script)
i noted up some ifi lines what im not certain about myself (with the red text)

And i still get this error:
[Warning - NpcScript::NpcScript] Can not load script:
cannot open data/npc/scripts/: Permission denied

EDIT:
NO ACCES DENIED ERROR ANYMORE!
i had another npc.xml for testing, but it missed script..
so it gave that error. not the task master.
 
Last edited:
i updated all the changes you suggested for tasks.lua (red text is not in the script)
i noted up some ifi lines what im not certain about myself (with the red text)

And i still get this error:
[Warning - NpcScript::NpcScript] Can not load script:
cannot open data/npc/scripts/: Permission denied

EDIT:
I think the permission denied comes from the NPC looktype.. gona check that out.
This is because the script is completely written improperly, you should read this tutorial by @Limos
http://otland.net/threads/npc-mission.211063/

If you have read it again, even I'm reading it lol

If you know the basics then you can fine tune or update what you have learned but if all you do is copy and paste and then try to update it it won't work as expected.

Don't get me wrong I did started updating your script but then I ran into a problem it wasn't executing properly so I decided to hold off and learn the basics at the very least.
 
Last edited by a moderator:
i am using that guide for ground work, but i simply trying to add my own "touch" to it.
completely written improperly?
what part?

Anway the new error comes from this line (i kinda knew i messed up here, because well, made it with my own logic)
tasks:lua:30: attempt to index a nil value

local startTask = doCreatureSetStorage(cid, tasks[msg].questStarted, 1)

how should i change it?


same nil value problem here:
if getCreatureStorage(cid, tasks["deer"].questStarted) == 1 then
(i could and prolly fix this by changing the playerStorage value instead. Easier to call..)
 
Last edited:
i updated tasks.lua

if levelRange then
is doing nothing.. it gives same tasks to everyone.

Pulling StorageValues instead of creature values also made progress in live npc chat.

put now error comes with this:
It says this is a Nil Value.
local startTaskSay = selfSay ("You accepted task to kill" .. tasks[msg].killsRequired .. " " .. tasks[msg].raceName .. "", cid)
 
i updated tasks.lua

if levelRange then
is doing nothing.. it gives same tasks to everyone.

Pulling StorageValues instead of creature values also made progress in live npc chat.

put now error comes with this:
It says this is a Nil Value.
local startTaskSay = selfSay ("You accepted task to kill" .. tasks[msg].killsRequired .. " " .. tasks[msg].raceName .. "", cid)
I didn't say to add them to your script, what I did say was that I rewrote your script and those were the functions I made.

I guess it doesn't matter because your not paying attention to anything I am typing anyway, good luck with your npc
 
shows what?

as far as i understand from your script:
function getTasks(table_, level, index, range)
Is making table

function canDoTask(table_, msg, state, level)
check if level is correct

function need(player)
checks how many mosnters killed

function levelRange(level, min, max)
checks if level is correct? again?

But there function only return information, but nothing will change..
 
shows what?
That your not reading or getting what I typed, I was showing you the progress but you seem to be too dense to understand even that much.

Figure it out yourself.

Wait let me use caps
FIGURE IT OUT YOURSELF

wait bigger font maybe color coordinated?
FIGURE IT OUT YOUR SELF
 
That your not reading or getting what I typed, I was showing you the progress but you seem to be too dense to understand even that much

well, i'm sorry that i don't understand how your script works and still tried to use it..
Since you don't want to explain me the script you made for me i will just slowly progress with the script my own.

Prolly going to loose local tasks {} because i don't know how to pull information out of it.. effectivly

tasks.lua is working now as intended.

Only problem is that if i want to add new task i have to add it to 4 different sections. (ain't that big of a problem though)
1. tasks array
2. npc hint list
3. list of acceptable tasks
4. task checking and rewarding

I will now try to make onKill work.

big changes in post1

Now my problem is that, my onKill events are not working.
It doesn't even give errors
 
Last edited by a moderator:
Code:
<event type="kill" name="tasks" event="script" value="tasks.lua"/>
This is not correct, should be: script="tasks.lua"
So without event and value, that is for TFS 0.3/0.4.
 
Code:
<event type="kill" name="tasks" event="script" value="tasks.lua"/>
This is not correct, should be: script="tasks.lua"
So without event and value, that is for TFS 0.3/0.4.


ok, thx, i found more method what was TFS 0.4 method..
but cant test it right them right now..
my computer crashed and when i turned back on. i have no access to MySQL... trying to figure out the problem for that xD

edit:
btw if you take away my double post. i cant edit post 1. i have over 10k characters
 
alright, my NPC is now working
It gives tasks, and checks the status correctly

Creaturescript correctly gives messages and all is fine.

But this is still not enough.

How to add interval for storage values?
Lets say if Storage value = -2 then you have to wait 6hours
when 6 hours has passed then storage value is set to = -1 (which allow players to take task again) [don't mind code atm, i will alter if its even possible to add intervals to storagevalue]
 
Last edited:
Back
Top