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

Lua Script - Task NPC Grizzly Adams.

Eldran

New Member
Joined
Jul 13, 2009
Messages
85
Reaction score
1
The NPC lets you do the same task countless times always giving the reward for it. I want to restrict players from doing only 1x each task. I using OTHire 0.0.3 distribution.


NPC Script:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}

function onCreatureAppear(cid) npcHandler:eek:nCreatureAppear(cid) end
function onCreatureDisappear(cid) npcHandler:eek:nCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg) npcHandler:eek:nCreatureSay(cid, type, msg) end
function onThink() npcHandler:eek:nThink() end

local choose = {}
local cancel = {}
local available = {}
function creatureSayCallback(cid, type, msg)

if npcHandler.focus ~= cid then
return false
end
local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_PRIVATE and 0 or cid

if isInArray({"tasks", "task", "mission"}, msg:lower()) then
local can = getTasksByPlayer(cid)
if #can > 0 then
local text = ""
local sep = ", "
table.sort(can, (function(a, b) return (a < b) end))
local t = 0
for _, id in ipairs(can) do
t = t + 1
if t == #can - 1 then
sep = " and "
elseif t == #can then
sep = "."
end
text = text .. "{" .. (tasks[id].name or tasks[id].raceName) .. "}" .. sep
end
selfSay("The current task" .. (#can > 1 and "s" or "") .. " that you can choose " .. (#can > 1 and "are" or "is") .. " " .. text)
talkState[talkUser] = 0
else
selfSay("I don't have any task for you right now.")
end
elseif msg ~= "" and canStartTask(cid, msg) then
if #getPlayerStartedTasks(cid) >= tasksByPlayer then
selfSay("Sorry, but you already started " .. tasksByPlayer .. " tasks.")
return true
end
local task = getTaskByName(msg)
if task and getPlayerStorageValue(cid, QUESTSTORAGE_BASE + task) > 0 then
return false
end
selfSay("In this task you must defeat " .. tasks[task].killsRequired .. " " .. tasks[task].raceName .. ". Are you sure that you want to start this task?")
choose[cid] = task
talkState[talkUser] = 1
elseif msg:lower() == "yes" and talkState[talkUser] == 1 then
setPlayerStorageValue(cid, QUESTSTORAGE_BASE + choose[cid], 1)
selfSay("Excellent! You can check the status of your task saying report to me.")
choose[cid] = nil
talkState[talkUser] = 0
elseif msg:lower() == "report" then
local started = getPlayerStartedTasks(cid)
local finishedAtLeastOne = false
local finished = 0
if started and #started > 0 then
for _, id in ipairs(started) do
if getPlayerStorageValue(cid, KILLSSTORAGE_BASE + id) >= tasks[id].killsRequired then
for _, reward in ipairs(tasks[id].rewards) do
print("Rewards loaded")
local deny = false
if reward.storage then
if getPlayerStorageValue(cid, reward.storage[1]) >= reward.storage[2] then
deny = true
end
end
if isInArray({REWARD_MONEY, "money"}, reward.type:lower()) and not deny then
doPlayerAddMoney(cid, reward.value[1])
elseif isInArray({REWARD_EXP, "exp", "experience"}, reward.type:lower()) and not deny then
doPlayerAddExp(cid, reward.value[1])
doPlayerSendDefaultCancel(cid, "You gained " .. reward.value[1] .. " experience points.")
elseif isInArray({REWARD_ACHIEVEMENT, "achievement", "ach"}, reward.type:lower()) and not deny then
if doPlayerAddAchievement then
doPlayerAddAchievement(cid, reward.value[1], true)
end
elseif isInArray({REWARD_STORAGE, "storage", "stor"}, reward.type:lower()) and not deny then
setPlayerStorageValue(cid, reward.value[1], reward.value[2])
elseif isInArray({REWARD_POINT, "points", "point"}, reward.type:lower()) and not deny then
setPlayerStorageValue(cid, POINTSSTORAGE, getPlayerStorageValue(cid, POINTSSTORAGE) + reward.value[1])
elseif isInArray({REWARD_ITEM, "item", "items", "object"}, reward.type:lower()) and not deny then
doPlayerAddItem(cid, reward.value[1], reward.value[2])
end

if reward.storage then
setPlayerStorageValue(cid, reward.storage[1], reward.storage[2])
end
end

if tasks[id].norepeatable then
setPlayerStorageValue(cid, QUESTSTORAGE_BASE + id, 2)
else
setPlayerStorageValue(cid, QUESTSTORAGE_BASE + id, 0)
end
setPlayerStorageValue(cid, KILLSSTORAGE_BASE + id, 0)
if getPlayerStorageValue(cid, REPEATSTORAGE_BASE + id) < 1 then
setPlayerStorageValue(cid, REPEATSTORAGE_BASE + id, 0)
end
setPlayerStorageValue(cid, REPEATSTORAGE_BASE + id, getPlayerStorageValue(cid, REPEATSTORAGE_BASE + id) + 1)
finishedAtLeastOne = true
finished = finished + 1
end
end

if not finishedAtLeastOne then
selfSay("You haven't finished any task yet.")
else
selfSay("Awesome! you finished " .. (finished > 1 and "various" or "a") .. " task" .. (finished > 1 and "s" or "") .. ". Talk to me again if you want to start a task.")
end
else
selfSay("You haven't started any task yet.")
end
elseif msg:lower() == "started" then
local started = getPlayerStartedTasks(cid)
if started and #started > 0 then
local text = ""
local sep = ", "
table.sort(started, (function(a, b) return (a < b) end))
local t = 0
for _, id in ipairs(started) do
t = t + 1
if t == #started - 1 then
sep = " and "
elseif t == #started then
sep = "."
end
text = text .. "{" .. (tasks[id].name or tasks[id].raceName) .. "}" .. sep
end

selfSay("The current task" .. (#started > 1 and "s" or "") .. " that you started " .. (#started > 1 and "are" or "is") .. " " .. text)
else
selfSay("You haven't started any task yet.")
end
elseif msg:lower() == "cancel" then
local started = getPlayerStartedTasks(cid)
if started and #started > 0 then
selfSay("Cancelling a task will make the count restart. Wich task you want to cancel?")
talkState[talkUser] = 2
else
selfSay("You haven't started any task yet.")
end
elseif getTaskByName(msg) and talkState[talkUser] == 2 and isInArray(getPlayerStartedTasks(cid), getTaskByName(msg)) then
local task = getTaskByName(msg)
if getPlayerStorageValue(cid, KILLSSTORAGE_BASE + task) > 0 then
selfSay("You currently killed " .. getPlayerStorageValue(cid, KILLSSTORAGE_BASE + task) .. "/" .. tasks[task].killsRequired .. " " .. tasks[task].raceName .. ". Cancelling this task will restart the count. Are you sure you want to cancel this task?")
else
selfSay("Are you sure you want to cancel this task?")
end
talkState[talkUser] = 3
cancel[cid] = task
elseif msg:lower() == "yes" and talkState[talkUser] == 3 then
setPlayerStorageValue(cid, QUESTSTORAGE_BASE + cancel[cid], -1)
setPlayerStorageValue(cid, KILLSSTORAGE_BASE + cancel[cid], -1)
selfSay("You have cancelled the task " .. (tasks[cancel[cid]].name or tasks[cancel[cid]].raceName) .. ".")
talkState[talkUser] = 0
elseif isInArray({"points", "rank"}, msg:lower()) then
selfSay("At this time, you have " .. getPlayerStorageValue(cid, POINTSSTORAGE) .. " Paw & Fur points. You " .. (getPlayerRank(cid) == 5 and "are an Elite Hunter" or getPlayerRank(cid) == 4 and "are a Trophy Hunter" or getPlayerRank(cid) == 3 and "are a Big Game Hunter" or getPlayerRank(cid) == 2 and "are a Ranger" or getPlayerRank(cid) == 1 and "are a Huntsman" or "haven't been ranked yet") .. ".")
talkState[talkUser] = 0
end
end

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

Lib:
  1. -- TASK


  2. RANK_NONE = 0
  3. RANK_HUNTSMAN = 1
  4. RANK_RANGER = 2
  5. RANK_BIGGAMEHUNTER = 3
  6. RANK_TROPHYHUNTER = 4
  7. RANK_ELITEHUNTER = 5

  8. REWARD_MONEY = 1
  9. REWARD_EXP = 2
  10. REWARD_ACHIEVEMENT = 3
  11. REWARD_STORAGE = 4
  12. REWARD_POINT = 5
  13. REWARD_ITEM = 6

  14. QUESTSTORAGE_BASE = 71500
  15. KILLSSTORAGE_BASE = 72500
  16. REPEATSTORAGE_BASE = 73500
  17. POINTSSTORAGE = 72500
  18. ONTASKSTORAGE = 74500
  19. tasks =
  20. {
  21. [1] = {killsRequired = 50, raceName = "Noob", level = {1, 666}, premium = false, creatures = {"rat", "cave rat", "spider", "poison spider", "bug"}, rewards = {
  22. {type = "exp", value = {8000}},
  23. {type = "money", value = {5000}},
  24. {type = "points", value = {1}},
  25. {type = "storage", value = {81500,1}}
  26. }},
  27. [2] = {killsRequired = 50, raceName = "Orcs", level = {1, 666}, premium = false, creatures = {"orc", "orc warrior", "orc spearman", "orc berserker", "orc leader"}, rewards = {
  28. {type = "exp", value = {10000}},
  29. {type = "money", value = {3500}},
  30. {type = "points", value = {1}}
  31. }},
  32. [3] = {bkillsRequired = 300, raceName = "Crocodiles", level = {1, 666}, premium = false, creatures = {"crocodile"}, rewards = {
  33. {type = "exp", value = {20000}},
  34. {type = "item", value = {2536,1}},
  35. {type = "points", value = {1}},
  36. {type = "storage", value = {81500,3}}
  37. }},
  38. [4] = {killsRequired = 300, raceName = "Tarantulas", level = {1, 666}, premium = false, creatures = {"tarantula"}, rewards = {
  39. {type = "exp", value = {30000}},
  40. {type = "points", value = {1}},
  41. {type = "storage", value = {81500,4}}
  42. }},
  43. [5] = {killsRequired = 150, raceName = "Carniphilas", level = {1, 666}, premium = false, creatures = {"carniphila"}, rewards = {
  44. {type = "exp", value = {30000}},
  45. {type = "item", value = {2477,1}},
  46. {type = "points", value = {1}},
  47. {type = "storage", value = {81500,5}}
  48. }}
  49. }

  50. tasksByPlayer = 3
  51. repeatTimes = 3

  52. function getPlayerRank(cid)
  53. return (getPlayerStorageValue(cid, POINTSSTORAGE) >= 100 and RANK_ELITEHUNTER or getPlayerStorageValue(cid, POINTSSTORAGE) >= 70 and RANK_TROPHYHUNTER or getPlayerStorageValue(cid, POINTSSTORAGE) >= 40 and RANK_BIGGAMEHUNTER or getPlayerStorageValue(cid, POINTSSTORAGE) >= 20 and RANK_RANGER or getPlayerStorageValue(cid, POINTSSTORAGE) >= 10 and RANK_HUNTSMAN or RANK_NONE)
  54. end

  55. function getTaskByName(name, table)
  56. local t = (table and table or tasks)
  57. for k, v in pairs(t) do
  58. if v.name then
  59. if v.name:lower() == name:lower() then
  60. return k
  61. end
  62. else
  63. if v.raceName:lower() == name:lower() then
  64. return k
  65. end
  66. end
  67. end
  68. return false
  69. end

  70. function getTasksByPlayer(cid)
  71. local canmake = {}
  72. local able = {}
  73. for k, v in pairs(tasks) do
  74. if getPlayerStorageValue(cid, QUESTSTORAGE_BASE + k) < 1 and getPlayerStorageValue(cid, REPEATSTORAGE_BASE + k) < repeatTimes then
  75. able[k] = true
  76. if getPlayerLevel(cid) < v.level[1] or getPlayerLevel(cid) > v.level[2] then
  77. able[k] = false
  78. end
  79. if v.storage and getPlayerStorageValue(cid, v.storage[1]) < v.storage[2] then
  80. able[k] = false
  81. end

  82. if v.rank then
  83. if getPlayerRank(cid) < v.rank then
  84. able[k] = false
  85. end
  86. end

  87. if v.premium then
  88. if not isPremium(cid) then
  89. able[k] = false
  90. end
  91. end

  92. if able[k] then
  93. table.insert(canmake, k)
  94. end
  95. end
  96. end
  97. return canmake
  98. end


  99. function canStartTask(cid, name, table)
  100. local v = ""
  101. local id = 0
  102. local t = (table and table or tasks)
  103. for k, i in pairs(t) do
  104. if i.name then
  105. if i.name:lower() == name:lower() then
  106. v = i
  107. id = k
  108. break
  109. end
  110. else
  111. if i.raceName:lower() == name:lower() then
  112. v = i
  113. id = k
  114. break
  115. end
  116. end
  117. end
  118. if v == "" then
  119. return false
  120. end
  121. if getPlayerStorageValue(cid, QUESTSTORAGE_BASE + id) > 0 then
  122. return false
  123. end
  124. if (getPlayerStorageValue(cid, REPEATSTORAGE_BASE + id) >= repeatTimes) or (v.norepeatable and getPlayerStorageValue(cid, REPEATSTORAGE_BASE + id) > 0) then
  125. return false
  126. end
  127. if getPlayerLevel(cid) >= v.level[1] and getPlayerLevel(cid) <= v.level[2] then
  128. if v.premium then
  129. if isPremium(cid) then
  130. if v.rank then
  131. if getPlayerRank(cid) >= v.rank then
  132. if v.storage then
  133. if getPlayerStorageValue(cid, v.storage[1]) >= v.storage[2] then
  134. return true
  135. end
  136. else
  137. return true
  138. end
  139. end
  140. else
  141. return true
  142. end
  143. end
  144. else
  145. return true
  146. end
  147. end
  148. return false
  149. end

  150. function getPlayerStartedTasks(cid)

  151. local tmp = {}
  152. for k, v in pairs(tasks) do
  153. if getPlayerStorageValue(cid, QUESTSTORAGE_BASE + k) > 0 and getPlayerStorageValue(cid, QUESTSTORAGE_BASE + k) < 2 then
  154. table.insert(tmp, k)
  155. end
  156. end
  157. return tmp
  158. end

  159. function isSummon(target)
  160. return (getCreatureMaster(target) ~= target)
  161. end
 
Last edited:
Back
Top