RevScript Custom Task System

Alex

Miembro del equipo
Webdesigner
LV
58
 
Awards
38
Hola a todos,

Hoy les mostraré como hacer un custom Task System,

Ventajas: task 1 sola vez o task repetible, recompensa y xp.
Desventajas: 1 Task por Npc, deberan hacer tantos npc como tasks desean.

Vale lo primero, debereis crear un NPC, y dentro del npc pondreis este codigo:

NPC.XML

Código:
<?xml version="1.0" encoding="UTF-8"?>
<npc name="nombre_del_npc" walkinterval="1500" speed="100" walkradius="2" floorchange="0" script="nombre_del_npc.lua">
    <health max="100" now="100"/>
    <look type="540" head="0" body="0" legs="0" feet="0" addons="0" mount="0"/>
    <parameters>
        <parameter key="message_greet" value="Hello dear |PLAYERNAME|! Are you looking for a {task} ?." /> -- mensaje que dira
    </parameters>
</npc>

El nombre del npc, si quereis poner espacios sera: nombre_del_npc, sino no funcionara. aconsejo no complicarse y darle un nombre sin espacios.
Le poneis el Looktype que quereis.

En Npc/script , npc.lua, creareis el archivo con el nombre del NPC.LUA que le disteis en npc.xml, le pondreis este codigo dentro:

Código:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}

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 storage = 6227 -- Numero de Storage que le pondreis al NPC, recordad este numero

function creatureSayCallback(cid, type, msg)
     if not npcHandler:isFocused(cid) then
         return false
     end
     local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid

     if msgcontains(msg, "task") then -- "task" sera lo que le direis al npc, si quereis marcarlo en npc.Lua poneis por ejemplo: Are you looking for a {task} ? y el player dira task.
         if getPlayerStorageValue(cid, storage) == -1 then
             selfSay("I have a rude Task for you, did you accept to Kill 500 Brachiodemons and 500 Infernal Demons?", cid) -- mensaje de la task
             talkState[talkUser] = 1
         elseif getPlayerStorageValue(cid, storage) == 1 then
             selfSay("Did you kill 500 Brachiodemons and 500 Infernal Demons?", cid) -- mensaje de preguntar si los ha matado
             talkState[talkUser] = 1
         else
             selfSay("You already did the task, you can do it only one time.", cid) -- en el caso que pondreis la task limitada, una sola vez, dira este mensaje
         end
     elseif msgcontains(msg, "yes") and talkState[talkUser] == 1 then -- "yes" dejarlo asi
         if getPlayerStorageValue(cid, storage) == -1 then
             selfSay("Good, come back when you killed them.", cid) -- lo que dira despues que cogas la mission
             setPlayerStorageValue(cid, storage, 1)
         else
             if getPlayerStorageValue(cid, 38111) == 500 and getPlayerStorageValue(cid, 38112) == 500 then -- Aqui Importante, en el primer parentesis el 38111 y en el segundo 38112 sera la storage del script siguiente, el 500 corresponde a 500 kills en cada == , poneis los kills que deseais.
                 selfSay("Good job, here is your reward.", cid) -- mensaje del reward
                 doPlayerAddItem(cid, 2160, 15) -- Doplayeradditem aqui dara 15 Crystal coins, ID, Numero. Podeis copiar y pegar esta linea debajo tanto como querais de items rewards
                 doPlayerAddItem(cid, 2160, 15)
                 doPlayerAddItem(cid, 2160, 15)
                 doPlayerAddExp(cid, 15000000) -- la XP Que dara
                 setPlayerStorageValue(cid, 38111, 0) -- Aqui la parte interessante, el 38111 y 38112 , son los storages de arriba, si lo dejais asi, la task sera repetible al infinito, si lo quitais la task no se podra volver a hacer.
                 setPlayerStorageValue(cid, 38112, 0) -- igual
             else
                 selfSay("You didn't kill them all.", cid) -- mensaje de cuando no los han matado
             end
         end
         talkState[talkUser] = 0
     elseif msgcontains(msg, "no") and talkState[talkUser] == 1 then
         selfSay("Ok then.", cid)
         talkState[talkUser] = 0
     end
     return true
end

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

Despues vamos a ir en data/scripts/creaturescripts , creareis una carpeta llamada task, y dentro creareis un nuevo lua ( copia y pega cualquier otro archivo ), borrar todo dentro y poner este codigo:

Código:
local taskOneOnKill = CreatureEvent("taskoneonKill") -- nombre importante que pondreis en el login.php lo vereis despues, tiene que cambiar en cada fichero, igual para local taskOneOnKill, cada uno con un nombre distinto

local config = {
     ['brachiodemon'] = {amount = 500, storage = 38111, startstorage = 6227, startvalue = 1}, -- brachiodemon , nombre exacto del monstruo, amount = cuantos para matar , el storage = igual que arriba en npc.lua , el startstorage es el storage que hemos puesto al npc 6227
     ['infernal demon'] = {amount = 500, storage = 38232, startstorage = 6227, startvalue = 1},
}
function taskOneOnKill.onKill(cid, target) -- aqui hay un taskoneonkill este si creais uno con este nombre el siguiente lo debereis de llamar distinto
     local monster = config[getCreatureName(target):lower()]
     if isPlayer(target) or not monster or isSummon(target) then
         return true
     end

     if (getPlayerStorageValue(cid, monster.storage)+1) < monster.amount and getPlayerStorageValue(cid, monster.startstorage) >= monster.startvalue then
         setPlayerStorageValue(cid, monster.storage, getPlayerStorageValue(cid, monster.storage) + 1)
         doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, '[Task message]: '..(getPlayerStorageValue(cid, monster.storage)+1)..' of '..monster.amount..' '..getCreatureName(target)..'s killed.')
     end
     if (getPlayerStorageValue(cid, monster.storage)+1) == monster.amount then
         doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, 'Congratulations, you have killed '..(getPlayerStorageValue(cid, monster.storage)+1)..' '..getCreatureName(target)..'s and completed the '..getCreatureName(target)..'s mission.') -- mensaje que dira en la pantalla al matar los monsters
         setPlayerStorageValue(cid, monster.storage, getPlayerStorageValue(cid, monster.storage) + 1)
     end
     return true
end

taskOneOnKill:register() -- taskone de nuevo a cambiar si haceis varios npc

Luego iremos en login.lua, que esta en data/scripts/creaturescripts/others, buscaremos esta linea:

Código:
if player:getLastLoginSaved() == 0 then
        player:sendOutfitWindow()
        local backpack = player:addItem(1988)
        if backpack then
            for i = 1, #items do
                backpack:addItem(items[i][1], items[i][2])
            end
        end
        player:addItem(2050, 1, true, 1, CONST_SLOT_AMMO)
    else
               <------------------ AQUI PONDREIS EL CODIGO CADA VEZ UNO DEBAJO DEL OTRO
Código:
player:sendTextMessage(MESSAGE_STATUS_DEFAULT, string.format("Your last visit in ".. SERVER_NAME ..": %s.", os.date("%d. %b %Y %X", player:getLastLoginSaved())))
Código:
end

Como veis en el script arriba escribi un mensaje, entre esas dos lineas copiareis este codigo, que si se acuerdan es el nombre que le dimos al script de arriba que debera cambiar cada vez.

Código:
player:registerEvent("taskoneonkill")

En teoria, si no teneis jugadores ( no lo lanzeis online, solo para vosotros probar, haceis un server save el dia siguiente y los jugadores al entrar tendran todos las tasks )
Podeis hacer el /reload scripts mientras esta online, logear fuera completamente, entrar de nuevo ( despues de reload scripts ), crear el NPC, hablar con el, coger la task y crear los monsters y matarlos, contara correctamente los monstruos kills.

PROBLEMA CONOCIDO:

Hay un problema conocido, que no és un problema en si, es el mismo que el Daily Reward, Preys y otros, que cuando llegais de Dawnport a Carlin o Thais o donde sea, una vez salido de dawnport, deberan los jugadores reloguear de nuevo, para ver los preys, daily reward, etc, pués con las Tasks pasa lo mismo, si la cogen sin haber logueado no se les contara, precisarles este detalle.
 
L

LeslieCam

Invitado
Hi Im getting this message
System Error ID 216 Task ID 1 Line - 0267.../../source/system/cflshmgr.cpp

Ive already changed the internal SD card and i dont know what to do next.
 

Alex

Miembro del equipo
Webdesigner
LV
58
 
Awards
38
Hi Im getting this message
System Error ID 216 Task ID 1 Line - 0267.../../source/system/cflshmgr.cpp

Ive already changed the internal SD card and i dont know what to do next.
Hello,
What tibia version are you using, protocol , tfs ?
This works on tfs 1.3, otservbr tested , 12.64.
 

Shuyin

Miembro
LV
23
 
Awards
17
he probado el script, pero he matado 1 de cada de los que pone al principio, y me dice que no los he matado y si los he matado.
No se si soy yo, o el script no va del todo bien.
 

Alex

Miembro del equipo
Webdesigner
LV
58
 
Awards
38
he probado el script, pero he matado 1 de cada de los que pone al principio, y me dice que no los he matado y si los he matado.
No se si soy yo, o el script no va del todo bien.

Lo tienes indicado en el tema
PROBLEMA CONOCIDO:

Hay un problema conocido, que no és un problema en si, es el mismo que el Daily Reward, Preys y otros, que cuando llegais de Dawnport a Carlin o Thais o donde sea, una vez salido de dawnport, deberan los jugadores reloguear de nuevo, para ver los preys, daily reward, etc, pués con las Tasks pasa lo mismo, si la cogen sin haber logueado no se les contara, precisarles este detalle

Si empiezas un nuevo char y llegas a Thais, como para el daily y los preys, debes de relogear, sino no funciona, aquí es lo mismo, una vez en Thais, desconectas y vuelves, si no lo haces te dirá que no los has matado. Esto solo ocurre por un nuevo player que llega a la main island, una vez reloggeado, ya no hace falta que se desconecten para todos los demás que incluirás.
 
Arriba