Informações:
- Tasks adquiridas ou canceladas em NPC
- As tasks podem ser feitas repetidas vezes, mas somente uma vez por dia e apenas uma de cada vez (tempo configurável)
- Comando para acompanhar o andamento da task
- Atualização (31/08/13) > agora é possível ganhar itens a cada vez que a task é terminada
- Atualização (05/09/13) > VÁRIOS bugs corrigidos e algumas novas opções adicionadas
- Agora você pode escolher se quer que as tasks sejam feitas por level ou na ordem
- Recomendo a todos os que baixaram alguma versão anterior que atualizem
Códigos:
Tags:
Em creaturescripts.xml, adicione:
<event type="kill" name="Tasks" script="taskkill.lua"/>
Em talkactions.xml, adicione:
<talkaction words="!countkills" event="script" value="countkills.lua"/>
No arquivo creaturescripts/scripts/login.lua, adicione:
registerCreatureEvent(cid, "Tasks")
Scripts:
- Crie um arquivo tasklib.lua em lib
-- Sistema de Task feito por Leoric (Omega no XTibia) --taskstg ={kills = 3451,permission = 3452,killstotal = 3453,monster = 3454,stage = 3455,points = 3456,}timeBetweenTasks = 24 * 60 * 60 -- tempo até poder fazer outra task (24 * 60 * 60 = 24hs)taskLevel = false -- true se quiser que as tasks sejam feitas por level / false se quiser que elas sejam feitas na ordemtaskMsg = {bool = true, msg = 'Voce acaba de matar monstros suficientes para completar sua task!'} -- bool = false > sem mensagens; bool = true > aviso quando terminar a tasktaskEnd = true -- [não tem função no modo Level] se estiver como true, quando o jogador terminar a última task disponível, ele não poderá repeti-la. Se estiver false, ele poderá repetir a última task infinitamente.taskmonsters ={[1] = {'rotworm', killstotal = 100}, -- aqui você deve mudar[2] = {'cyclop','cyclops','cyclops smith','cyclops drone', killstotal = 100},[3] = {'dragon','dragon lord','frost dragon', killstotal = 100}}taskreward = -- em gps{[1] = {money = 5000,xp = 20000, points = 3}, -- nenhum item será adicionado e 3 pontos de task serão adicionados[2] = {money = 10000,xp = 50000, item = 2458}, -- 1 item(2458) será adicionado e nenhum ponto de task[3] = {money = 20000,xp = 75000,item = 2458,amount = 2, points = 5} -- aqui serão adicionados 2 itens com id 2458 (se ele for amontoável - stackable) e 5 pontos de task}function canDoTask(cid) local stage = getPlayerStorageValue(cid, taskstg.stage) if stage + 1 > #taskmonsters then return false elseif getPlayerStorageValue(cid,taskstg.permission) <= 0 then return true elseif getPlayerStorageValue(cid,taskstg.permission) == 1 then return false elseif getPlayerStorageValue(cid,taskstg.permission) >= os.time(t) then return false end return trueendfunction doResetTask(cid) setPlayerStorageValue(cid,taskstg.kills,-1) setPlayerStorageValue(cid,taskstg.permission,os.time(t) + timeBetweenTasks) setPlayerStorageValue(cid,taskstg.killstotal,-1) setPlayerStorageValue(cid,taskstg.monster,-1) return trueendfunction doRewardTask(cid) local monster = getPlayerStorageValue(cid,taskstg.monster) local reward = taskreward[monster] if reward.item then doPlayerAddItem(cid,reward.item,(reward.amount and reward.amount or 1)) end if reward.points then local points = getPlayerStorageValue(cid, taskstg.points) if points == -1 then setPlayerStorageValue(cid, taskstg.points, 0) end setPlayerStorageValue(cid, taskstg.points, reward.points + points) end if monster and reward then doPlayerAddMoney(cid,reward.money) doPlayerAddExperience(cid, reward.xp) end return trueendfunction isSummon(cid) -- baseada na função do Vodkart if getCreatureMaster(cid) ~= nil or getCreatureMaster(cid) == true then return true end return falseendfunction doCompleteTask(cid) doRewardTask(cid) doResetTask(cid) return trueendfunction doStartTask(cid) if not taskLevel then local stage = getPlayerStorageValue(cid, taskstg.stage) if stage <= 0 then setPlayerStorageValue(cid, taskstg.monster, 1) setPlayerStorageValue(cid, taskstg.killstotal, taskmonsters[1].killstotal) setPlayerStorageValue(cid, taskstg.stage, 1) else setPlayerStorageValue(cid, taskstg.monster, stage+1) setPlayerStorageValue(cid, taskstg.killstotal, taskmonsters[stage+1].killstotal) if taskEnd or stage < #taskmonsters then setPlayerStorageValue(cid, taskstg.stage, stage+1) end end setPlayerStorageValue(cid, taskstg.permission, 1) setPlayerStorageValue(cid, taskstg.kills, 0) return true end local lvl = getPlayerLevel(cid) if lvl < 20 then local killstotal = taskmonsters[1].killstotal setPlayerStorageValue(cid,taskstg.monster,1) setPlayerStorageValue(cid,taskstg.killstotal,killstotal) setPlayerStorageValue(cid,taskstg.permission,1) elseif lvl < 50 then local killstotal = taskmonsters[2].killstotal setPlayerStorageValue(cid,taskstg.monster,2) setPlayerStorageValue(cid,taskstg.killstotal,killstotal) setPlayerStorageValue(cid,taskstg.permission,1) else local killstotal = taskmonsters[3].killstotal setPlayerStorageValue(cid,taskstg.monster,3) setPlayerStorageValue(cid,taskstg.killstotal,killstotal) setPlayerStorageValue(cid,taskstg.permission,1) end setPlayerStorageValue(cid,taskstg.kills,0) return trueend
- Crie um arquivo countkills.lua e adicione em talkactions/scripts
-- Sistema de Task feito por Leoric (Omega no XTibia) --function onSay(cid, words, param, channel) local monster, permission = getPlayerStorageValue(cid,taskstg.monster), getPlayerStorageValue(cid,taskstg.permission) local kills, killstotal = getPlayerStorageValue(cid,taskstg.kills), getPlayerStorageValue(cid,taskstg.killstotal) if monster == -1 or monster == 0 then doPlayerSendTextMessage(cid,27,'Voce nao tem nenhuma task ativa.') else local left = killstotal - kills if left <= 0 then doPlayerSendTextMessage(cid,27,'Voce ja matou monstros suficientes para terminar sua task.') else doPlayerSendTextMessage(cid,27,'Andamento da sua task de '..taskmonsters[monster][1]..'s -> ['..kills..'/'..killstotal..']') end end return trueend
- Crie um arquivo taskkill.lua em creaturescripts/scripts
-- Sistema de Task feito por Leoric (Omega no XTibia) --function onKill(cid, target) if not isPlayer(cid) then return true end if isSummon(target) then return true end local monster, permission = getPlayerStorageValue(cid,taskstg.monster), getPlayerStorageValue(cid,taskstg.permission) local kills, killstotal = getPlayerStorageValue(cid,taskstg.kills), getPlayerStorageValue(cid,taskstg.killstotal) if monster ~= -1 and monster ~= 0 then if isInArray(taskmonsters[monster],string.lower(getCreatureName(target))) then if kills == -1 then setPlayerStorageValue(cid,taskstg.kills,1) elseif kills + 1 == killstotal and taskMsg.bool == true then doPlayerSendTextMessage(cid, 21, taskMsg.msg) setPlayerStorageValue(cid,taskstg.kills,kills+1) else setPlayerStorageValue(cid,taskstg.kills,kills+1) end end end return trueend
- Crie um arquivo NomedoNPC.xml em npcs
<?xml version="1.0" encoding="UTF-8"?><npc name="NomedoNPC" script="data/npc/scripts/tasks.lua" walkinterval="3000" floorchange="0"> <health now="100" max="100"/> <look type="129" head="115" body="95" legs="113" feet="0" addons="3"/> <parameters> <parameter key="message_greet" value="Ei, |PLAYERNAME|, quer uma {nova task}, {informacoes} ou {cancelar} uma task? Ou sera que quer {completar} sua task? Huum... talvez ver quantos {pontos} voce tem?"/> <parameter key="message_farewell" value="Boa sorte em suas aventuras, |PLAYERNAME|."/> <parameter key="message_walkaway" value="Tchau... babaca."/> </parameters></npc>
- Crie um arquivo tasks.lua em npcs/scripts
-- Sistema de Task feito por Leoric (Omega no XTibia) --local keywordHandler = KeywordHandler:new()local npcHandler = NpcHandler:new(keywordHandler)NpcSystem.parseParameters(npcHandler)local talkState = {}function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) endfunction onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) endfunction onCreatureSay(cid, type, msg) npcHandler:onCreatureSay(cid, type, msg) endfunction onThink() npcHandler:onThink() endfunction creatureSayCallback(cid, type, msg) if(not npcHandler:isFocused(cid)) then return false end local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid local monster, permission = getPlayerStorageValue(cid,taskstg.monster), getPlayerStorageValue(cid,taskstg.permission) local kills, killstotal = getPlayerStorageValue(cid,taskstg.kills), getPlayerStorageValue(cid,taskstg.killstotal) if msgcontains(msg,'nova task') then if monster ~= -1 then selfSay('Você já tem uma task em andamento. Termine-a antes de começar outra.',cid) elseif getPlayerStorageValue(cid, taskstg.stage) + 1 > #taskmonsters then selfSay('Eu não tenho mais tasks para você.',cid) elseif not canDoTask(cid) then selfSay('Você deve esperar '..math.ceil((permission - os.time(t))/60)..' minutos até poder começar outra task.',cid) else doStartTask(cid) selfSay('Muito bem, utilize {!countkills} para acompanhar o andamento de sua task.',cid) end talkState[talkUser] = 0 elseif msgcontains(msg,'completar') then if canDoTask(cid) then selfSay('Você não tem uma task iniciada ainda... diga {nova task} para começar uma.',cid) elseif permission > 1 then selfSay('Você não tem uma task ativa... e só poderá começar outra mais tarde.',cid) elseif killstotal > 1 and kills >= killstotal then selfSay('Parabéns por completar sua task!',cid) doCompleteTask(cid) else selfSay('Você ainda não completou sua task.',cid) end talkState[talkUser] = 0 elseif msgcontains(msg,'info') then if canDoTask(cid) and (monster == 0 or monster == -1) then selfSay('Você pode começar uma task dizendo {nova task}. Assim que disser, uma nova task será atribuída a você dependendo do seu level e você poderá acompanhar seu andamento dizendo {!countkills}.',cid) else selfSay('Você pode acompanhar sua task pelo comando {!countkills}. Assim que terminar, me avise e você receberá seu prêmio em dinheiro e experiência.',cid) end talkState[talkUser] = 0 elseif msgcontains(msg, 'pontos') then local pontos = getPlayerStorageValue(cid, taskstg.points) > 0 and getPlayerStorageValue(cid, taskstg.points) or 0 selfSay('Você tem '.. pontos ..' pontos de task.',cid) elseif msgcontains(msg,'cancelar') then if monster == 0 or monster == -1 then selfSay('Você não tem uma task ativa para cancelar.',cid) talkState[talkUser] = 0 else selfSay('Você tem certeza que quer cancelar sua task?',cid) talkState[talkUser] = 1 end elseif (msgcontains(msg,'yes') or msgcontains(msg,'sim')) and talkState[talkUser] == 1 then selfSay('Muito bem, sua task foi cancelada.',cid) doResetTask(cid) setPlayerStorageValue(cid,taskstg.permission,-1) setPlayerStorageValue(cid, taskstg.stage, getPlayerStorageValue(cid, taskstg.stage)-1) talkState[talkUser] = 0 elseif (msgcontains(msg,'no') or msgcontains(msg,'não')) and talkState[talkUser] == 1 then selfSay('Você que sabe, né...',cid) endendnpcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)npcHandler:addModule(FocusModule:new())
Configuração:
É feita toda no tasklib.lua:
Configuração dos monstros:
taskmonsters ={[1] = {'rotworm', killstotal = 100},[2] = {'cyclop','cyclops','cyclops smith','cyclops drone', killstotal = 100},[3] = {'dragon','dragon lord','frost dragon', killstotal = 100}}
- O [número] deve seguir a ordem
- A primeira parte deve ser o nome dos monstros da task no singular. Por isso existem 'cyclop' (singular) e 'cyclops' (nome do monstro)
- Os nomes de todos os monstros de cada task devem aparecer. Por exemplo, na task de cyclops, qualquer tipo deles servirá para completar a task.
- killstotal é a quantidade de monstros que você deve matar para terminar a task.
Configuração das recompensas:
taskreward = -- em gps{[1] = {money = 5000,xp = 20000, points = 3}, -- nenhum item será adicionado e 3 pontos de task serão adicionados[2] = {money = 10000,xp = 50000, item = 2458}, -- 1 item(2458) será adicionado e nenhum ponto de task[3] = {money = 20000,xp = 75000,item = 2458,amount = 2, points = 5} -- aqui serão adicionados 2 itens com id 2458 (se ele for amontoável - stackable) e 5 pontos de task}
- O [número] deve ter a mesma ordem dos monstros
- money é a quantidade de dinheiro que cada um ganha ao terminar a task correspondente
- xp é a quantidade de experiência ganha ao terminar a task correspondente
- item é o ID do item que ganha ao terminar a task correspondente
- points significa quantos pontos de task o personagem irá ganhar quando terminar a task correspondente
Adicionando novos monstros:
- Vou explicar com um exemplo de como adicionar uma task de hydra/serpent spawn
No taskmonsters: (REPARE NA VÍRGULA QUANDO ADICIONEI UMA NOVA LINHA!)
taskmonsters ={[1] = {'rotworm', killstotal = 100},[2] = {'cyclop','cyclops','cyclops smith','cyclops drone', killstotal = 100},[3] = {'dragon','dragon lord','frost dragon', killstotal = 100},[4] = {'hydras e serpent spawn','hydra','serpent spawn',killstotal = 200}}
No taskrewards:
taskreward = -- em gps{[1] = {money = 5000,xp = 20000, points = 3}, -- nenhum item será adicionado e 3 pontos de task serão adicionados[2] = {money = 10000,xp = 50000, item = 2458}, -- 1 item(2458) será adicionado e nenhum ponto de task[3] = {money = 20000,xp = 75000,item = 2458,amount = 2, points = 5}, -- aqui serão adicionados 2 itens com id 2458 (se ele for amontoável - stackable) e 5 pontos de task[4] = {money = 30000, xp = 5000, item = 2450, amount = 1, points = 3}}
Agora na função doStartTask(cid) - somente se quiser que as tasks sejam feitas por level -
function doStartTask(cid) local lvl = getPlayerLevel(cid) if lvl < 20 then local killstotal = taskmonsters[1].killstotal setPlayerStorageValue(cid,taskstg.monster,1) setPlayerStorageValue(cid,taskstg.killstotal,killstotal) setPlayerStorageValue(cid,taskstg.permission,1) setPlayerStorageValue(cid,taskstg.kills,0) elseif lvl < 50 then local killstotal = taskmonsters[2].killstotal setPlayerStorageValue(cid,taskstg.monster,2) setPlayerStorageValue(cid,taskstg.killstotal,killstotal) setPlayerStorageValue(cid,taskstg.permission,1) setPlayerStorageValue(cid,taskstg.kills,0) elseif lvl < 80 then local killstotal = taskmonsters[3].killstotal setPlayerStorageValue(cid,taskstg.monster,3) setPlayerStorageValue(cid,taskstg.killstotal,killstotal) setPlayerStorageValue(cid,taskstg.permission,1) setPlayerStorageValue(cid,taskstg.kills,0) else local killstotal = taskmonsters[4].killstotal setPlayerStorageValue(cid,taskstg.monster,4) setPlayerStorageValue(cid,taskstg.killstotal,killstotal) setPlayerStorageValue(cid,taskstg.permission,1) setPlayerStorageValue(cid,taskstg.kills,0) end return trueend
O que aconteceu:
- Antes até o lvl 20 o jogador recebia a task dos rotworms, até o lvl 50, a task dos cyclops e daí pra frente, task dos dragons.
- As tasks iniciais são as mesmas, mas até o lvl 80 é a task dos dragons e daí pra frente, o jogador receberá a task das hydras e serpent spawns.
Considerações finais:
O sistema de pontos apenas adiciona e checa a quantidade de pontos: você deve escolher se quer adicionar alguma coisa a partir deles.
Testei profundamente e corrigi todos os erros que encontrei, postem se encontrarem mais algum, enviem o log do erro que farei o possível para consertar.