Script [TFS 1.3] Npc Item Task Package Deliver

Alex

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

Aquí les traigo un script que consiste en Tareas ( Tasks ) de entrega de armas, equipamiento o suministros.
Dependiendo de la elección del jugador, aparecerá una lista, dependiendo del Nivel acordado en el script.
Puede otorgar items rewards, experiencia, outfits, mounts, no se olviden que para esto si incluyen un outfit premium el jugador debe de ser premium para traerlo.

Los jugadores solo pueden tener una tarea a la vez, no hay tiempo para entregar una tarea y para obtener otra.
Cada tarea contiene una recompensa diferente.

XML Del Npc:

Código:
<?xml version="1.0" encoding="UTF-8"?>
<npc name="Tarea" script="tarea.lua" walkinterval="2000" floorchange="0">
    <health now="100" max="100" />
    <look type="139" head="20" body="39" legs="45" feet="7" addons="0" />
</npc>

Script Npc tarea.lua:

Código:
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 randomGreeting = {
    "Welcome back |PLAYERNAME|. Are you looking for a {task}?",
    "How are you today |PLAYERNAME|? Ask me for a {task}.",
    "Are you looking for a {task}, |PLAYERNAME|?"
}
local taskReplies = {}
local taskStorages = {45000, 45001, 45002, 45003} -- {task, choice, playerLevel, decision}
local tasks = {

    --[[
    Ensure that all tasks/choices/decisions are lowercase only. Do not use capitals.
    
    {task = "task 1",
        {choice = "choice 1",
            {levelRange = {1, 9}, -- level 1 to 9
                {decision = "decision 1",
                    deliveryDetails = {
                        {itemid = 1111, amount = 1}, -- will automatically fetch name of itemid
                        {itemid = 2222, amount = 2}
                    },
                    rewards = {
                        experience = 100,
                        money = 100, -- automatically converts to gold/plat/crystal
                        outfit = {outfitName = "name", looktypeMale = 111, looktypeFemale = 222},
                        addon = {outfitName = "name", looktypeMale = 111, looktypeFemale = 222, addon = 1}, -- addon 1 or 2 -> or 3 (both)
                        mount = {mountName = "name", mountId = 1},
                        items = {
                            {itemid = 1111, amount = {1, 1}}, -- amount = {minimum, maximum}
                            {itemid = 2222, amount = {2, 2}}
                        }
                    }
                }
            }
        }
    }
    ]]--
    
    -- weapons
    {task = "weapons",
        {choice = "swords",
            {levelRange = {1, 9},
                {decision = "package one",
                    deliveryDetails = {
                        {itemid = 2403, amount = 3}, -- knife
                        {itemid = 2148, amount = 50} -- gold coins
                    },
                    rewards = {
                        experience = 1000000,
                        money = 10203, -- automatically converts to gold/plat/crystal
                        outfit = {outfitName = "noble", looktypeMale = 132, looktypeFemale = 140},
                        addon = {outfitName = "noble", looktypeMale = 132, looktypeFemale = 140, addon = 1}, -- addon 1 or 2 -> or 3 (both)
                        mount = {mountName = "widow queen", mountId = 1},
                        items = {
                            {itemid = 2461, amount = {1, 1}}, -- amount = {minimum, maximum}
                            {itemid = 2467, amount = {1, 1}},
                            {itemid = 2649, amount = {1, 1}},
                            {itemid = 2643, amount = {1, 1}},
                            {itemid = 2667, amount = {5, 10}}
                        }
                    }
                },
                {decision = "package two",
                    deliveryDetails = {
                        {itemid = 13829, amount = 2}
                    },
                    rewards = {
                        experience = 200 -- you can remove rewards from the list, to make it less cluttered
                    }
                },
                {decision = "package three",
                    deliveryDetails = {
                        {itemid = 2404, amount = 1}
                    },
                    rewards = {} -- if a task has no rewards, just leave it empty like this
                }
            },
            
            {levelRange = {10, 30},
                {decision = "package four",
                    deliveryDetails = {
                        {itemid = 2385, amount = 2}
                    },
                    rewards = {
                        experience = 100
                    }
                },
                {decision = "package five",
                    deliveryDetails = {
                        {itemid = 2395, amount = 1}
                    },
                    rewards = {
                        experience = 100
                    }
                },
            }
        },
        {choice = "axes",
            {levelRange = {1, 9},
                {decision = "decision 1",
                    deliveryDetails = {
                        {itemid = 1111, amount = 1}
                    },
                    rewards = {
                        experience = 100,
                    }
                }
            }
        },
        {choice = "clubs",
            {levelRange = {1, 9},
                {decision = "decision 1",
                    deliveryDetails = {
                        {itemid = 1111, amount = 1}
                    },
                    rewards = {
                        experience = 100,
                    }
                }
            }
        },
        {choice = "claws",
            {levelRange = {1, 9},
                {decision = "decision 1",
                    deliveryDetails = {
                        {itemid = 1111, amount = 1}
                    },
                    rewards = {
                        experience = 100,
                    }
                }
            }
        },
        {choice = "daggers",
            {levelRange = {1, 9},
                {decision = "decision 1",
                    deliveryDetails = {
                        {itemid = 1111, amount = 1}
                    },
                    rewards = {
                        experience = 100,
                    }
                }
            }
        },
        {choice = "bows",
            {levelRange = {1, 9},
                {decision = "decision 1",
                    deliveryDetails = {
                        {itemid = 1111, amount = 1}
                    },
                    rewards = {
                        experience = 100,
                    }
                }
            }
        },
        {choice = "crossbows",
            {levelRange = {1, 9},
                {decision = "decision 1",
                    deliveryDetails = {
                        {itemid = 1111, amount = 1}
                    },
                    rewards = {
                        experience = 100,
                    }
                }
            }
        },
        {choice = "guns",
            {levelRange = {1, 9},
                {decision = "decision 1",
                    deliveryDetails = {
                        {itemid = 1111, amount = 1}
                    },
                    rewards = {
                        experience = 100,
                    }
                }
            }
        },
        {choice = "wands",
            {levelRange = {1, 9},
                {decision = "decision 1",
                    deliveryDetails = {
                        {itemid = 1111, amount = 1}
                    },
                    rewards = {
                        experience = 100,
                    }
                }
            }
        }
    },
    
    -- equipment
    {task = "equipment",
        {choice = "choice 1",
            {levelRange = {1, 9},
                {decision = "decision 1",
                    deliveryDetails = {
                        {itemid = 1111, amount = 1}
                    },
                    rewards = {
                        experience = 100,
                    }
                }
            }
        }
    },
    
    -- supplies
    {task = "supplies",
        {choice = "choice 1",
            {levelRange = {1, 9},
                {decision = "decision 1",
                    deliveryDetails = {
                        {itemid = 1111, amount = 1}
                    },
                    rewards = {
                        experience = 100,
                    }
                }
            }
        }
    }
}

local function indexTask(msg)
    local index = 0
    for i = 1, #tasks do
        if msg == tasks[i].task then
            index = i
            break
        end
    end
    return index
end

local function indexChoice(cid, msg)
    local index = 0
    local task = tasks[taskReplies[cid].taskIndex]
    for i = 1, #task do
        if msg == task[i].choice then
            index = i
            break
        end
    end
    return index
end

local function indexLevel(cid)
    local index = 0
    local task = tasks[taskReplies[cid].taskIndex][taskReplies[cid].choiceIndex]
    local player = Player(cid)
    local level = player:getLevel()
    for i = 1, #task do
        if level >= task[i].levelRange[1] and level <= task[i].levelRange[2] then
            index = i
            break
        end
    end
    return index
end

local function indexDecision(cid, msg)
    local index = 0
    local task = tasks[taskReplies[cid].taskIndex][taskReplies[cid].choiceIndex][taskReplies[cid].levelIndex]
    for i = 1, #task do
        if msg == task[i].decision then
            index = i
            break
        end
    end
    return index
end

local function listTasks()
    local text = ""
    for i = 1, #tasks do
        if text ~= "" then
            if #tasks == i then
                text = text .. " or "
            else
                text = text .. ", "
            end
        end
        text = text .. "{" .. tasks[i].task .. "}"
    end
    return text
end

local function listChoices(cid)
    local text = ""
    local task = tasks[taskReplies[cid].taskIndex]
    for i = 1, #task do
        if text ~= "" then
            if #task == i then
                text = text .. " or "
            else
                text = text .. ", "
            end
        end
        text = text .. "{" .. task[i].choice .. "}"
    end
    return text
end

local function listDecisions(cid)
    local text = ""
    local task = tasks[taskReplies[cid].taskIndex][taskReplies[cid].choiceIndex][taskReplies[cid].levelIndex]
    for i = 1, #task do
        if text ~= "" then
            if #task == i then
                text = text .. " or "
            else
                text = text .. ", "
            end
        end
        text = text .. "{" .. task[i].decision .. "}"
        
        local delivery = task[i].deliveryDetails
        local deliveryText = " ("
        for n = 1, #delivery do
            if deliveryText ~= " (" then
                deliveryText = deliveryText .. ", "
            end
            deliveryText = deliveryText .. delivery[n].amount .. " " .. (delivery[n].amount == 1 and ItemType(delivery[n].itemid):getName() or ItemType(delivery[n].itemid):getPluralName())
        end
        text = text .. deliveryText .. ")"
    end
    return text
end

local function getChosenTaskDeliveryDetails(chosenTask)
    local text = chosenTask.decision   
    local delivery = chosenTask.deliveryDetails
    local deliveryText = " ("
    for i = 1, #delivery do
        if deliveryText ~= " (" then
            deliveryText = deliveryText .. ", "
        end
        deliveryText = deliveryText .. delivery[i].amount .. " " .. (delivery[i].amount == 1 and ItemType(delivery[i].itemid):getName() or ItemType(delivery[i].itemid):getPluralName())
    end
    text = text .. deliveryText .. ")"
    return text
end

local function findMissingDeliveryItems(cid, chosenTask)
    local delivery = chosenTask.deliveryDetails
    local missingItems = ""
    local player = Player(cid)
    for i = 1, #delivery do
        if player:getItemCount(delivery[i].itemid) < delivery[i].amount then
            if missingItems ~= "" then
                missingItems = missingItems .. ", "
            end
            local missingAmount = delivery[i].amount - player:getItemCount(delivery[i].itemid)
            missingItems = missingItems .. missingAmount .. " " .. (missingAmount == 1 and ItemType(delivery[i].itemid):getName() or ItemType(delivery[i].itemid):getPluralName())
        end
    end
    return missingItems
end

local function removeDeliveryItems(cid, chosenTask)
    local delivery = chosenTask.deliveryDetails
    local player = Player(cid)
    for i = 1, #delivery do
        player:removeItem(delivery[i].itemid, delivery[i].amount)
    end
    return
end

local function deliverRewards(cid, chosenTask)   
    local text = ""
    local rewardList = chosenTask.rewards
    local player = Player(cid)
    
    if rewardList.experience then
        if text ~= "" then
            text = text .. ", "
        end
        text = rewardList.experience .. " experience"
        player:addExperience(rewardList.experience)
    end
    
    if rewardList.money then
        if text ~= "" then
            text = text .. ", "
        end
        text = text .. rewardList.money .. " gold coins"
        player:addMoney(rewardList.money)
    end
    
    if rewardList.outfit then
        if text ~= "" then
            text = text .. ", "
        end
        text = text .. rewardList.outfit.outfitName .. " outfit"
        player:addOutfit(rewardList.outfit.looktypeMale)
        player:addOutfit(rewardList.outfit.looktypeFemale)
    end
    
    if rewardList.addon then
        if text ~= "" then
            text = text .. ", "
        end
        text = text .. (rewardList.addon.addon == 1 and "first" or rewardList.addon.addon == 2 and "second" or "first and second") .. " addon for the " .. rewardList.addon.outfitName .. " outfit"
        player:addOutfitAddon(rewardList.addon.looktypeMale, rewardList.addon.addon)
        player:addOutfitAddon(rewardList.addon.looktypeFemale, rewardList.addon.addon)
    end
    
    if rewardList.mount then
        if text ~= "" then
            text = text .. ", "
        end
        text = text .. rewardList.mount.mountName .. " mount"
        player:addMount(rewardList.mount.mountId)
    end
    
    if rewardList.items then
        rewardList = rewardList.items
        local randAmount
        for i = 1, #rewardList do
            randAmount = math.random(rewardList[i].amount[1], rewardList[i].amount[2])
            if randAmount > 0 then
                if text ~= "" then
                    text = text .. ", "
                end
                text = text .. randAmount .. " " .. (randAmount == 1 and ItemType(rewardList[i].itemid):getName() or ItemType(rewardList[i].itemid):getPluralName())
                player:addItem(rewardList[i].itemid, randAmount, true)
            end
        end
    end
    
    if text == "" then
        text = "No reward for this task."
    end
    return text
end

local function greetCallback(cid)   
    npcHandler:setMessage(MESSAGE_GREET, randomGreeting[math.random(#randomGreeting)])
    return true
end

local function creatureSayCallback(cid, type, msg)
    if not npcHandler:isFocused(cid) then
        return false
    end
    
    local player = Player(cid)
    msg = msg:lower()
    
    -- if no task started
    if player:getStorageValue(taskStorages[1]) == -1 then
        if msgcontains(msg, "task") then
            npcHandler:say("Would you like to deliver " .. listTasks() .. "?", cid)
            npcHandler.topic[cid] = 1
            return true
        
        elseif npcHandler.topic[cid] == 1 then
            local taskIndex = indexTask(msg)
            if taskIndex == 0 then
                npcHandler:say("That's not on my list of items to deliver. Would you prefer to deliver " .. listTasks() .. "?", cid)
                return true
            end
            
            taskReplies[cid].taskIndex = taskIndex
            npcHandler:say("Would you like to deliver " .. listChoices(cid) .. "?", cid)
            npcHandler.topic[cid] = 2
            return true
        
        elseif npcHandler.topic[cid] == 2 then
            local choiceIndex = indexChoice(cid, msg)
            if choiceIndex == 0 then
                npcHandler:say("That's not on my list of items to deliver. Would you prefer to deliver " .. listChoices(cid) .. "?", cid)
                return true
            end
            taskReplies[cid].choiceIndex = choiceIndex
            
            local levelIndex = indexLevel(cid)
            if levelIndex == 0 then
                npcHandler:say("I don't have any " .. msg .. " that you can deliver at your current level. Try another option.", cid)
                return true
            end
            
            taskReplies[cid].levelIndex = levelIndex
            npcHandler:say("Would you like to deliver " .. listDecisions(cid) .. "?", cid)
            npcHandler.topic[cid] = 3
            return true
            
        elseif npcHandler.topic[cid] == 3 then
            local decisionIndex = indexDecision(cid, msg)
            if decisionIndex == 0 then
                npcHandler:say("That's not on my list of items to deliver. Would you prefer to deliver " .. listDecisions(cid) .. "?", cid)
                return true
            end
            
            taskReplies[cid].decisionIndex = decisionIndex
            npcHandler:say("Alright. Ask me about your {task} when you are ready to deliver.", cid)
            player:setStorageValue(taskStorages[1], taskReplies[cid].taskIndex)
            player:setStorageValue(taskStorages[2], taskReplies[cid].choiceIndex)
            player:setStorageValue(taskStorages[3], taskReplies[cid].levelIndex)
            player:setStorageValue(taskStorages[4], taskReplies[cid].decisionIndex)
            taskReplies[cid] = {}
            npcHandler.topic[cid] = 0
            return true
            
        end
    
    -- if task started
    else
        local task = player:getStorageValue(taskStorages[1])
        local choice = player:getStorageValue(taskStorages[2])
        local level = player:getStorageValue(taskStorages[3])
        local decision = player:getStorageValue(taskStorages[4])
        local chosenTask = tasks[task][choice][level][decision]
        
        if msgcontains(msg, "task") then
            npcHandler:say("Do you want to {deliver} " .. chosenTask.decision .. ", {confirm} the delivery details or {cancel} the delivery task?", cid)
            npcHandler.topic[cid] = 1
            return true
            
        elseif npcHandler.topic[cid] == 1 then
            if msgcontains(msg, "cancel") then
                npcHandler:say("Are you sure you want to cancel your task?", cid)
                npcHandler.topic[cid] = 2
                return true
            end
            if msgcontains(msg, "confirm") then
                npcHandler:say("You need to deliver " .. getChosenTaskDeliveryDetails(chosenTask) .. ".", cid)
                return true
            end
            if msgcontains(msg, "deliver") then
                npcHandler:say("You are you ready to deliver " .. chosenTask.decision .. "?", cid)
                npcHandler.topic[cid] = 3
                return true
            end
            npcHandler:say("Sorry? Do you want to {deliver}, {confirm} or {cancel}?", cid)
            return true
            
        elseif npcHandler.topic[cid] == 2 then
            if not msgcontains(msg, "yes") then
                npcHandler:say("Whew! Thought you were going to quit on me! Let me know when you want to {deliver} your task.", cid)
                npcHandler.topic[cid] = 1
                return true
            end
            
            npcHandler:say("Alright. Your delivery task has been cancelled. You can choose a new {task} when you are ready.", cid)
            player:setStorageValue(taskStorages[1], -1)
            player:setStorageValue(taskStorages[2], -1)
            player:setStorageValue(taskStorages[3], -1)
            player:setStorageValue(taskStorages[4], -1)
            npcHandler.topic[cid] = 0
            
        elseif npcHandler.topic[cid] == 3 then
            if not msgcontains(msg, "yes") then
                npcHandler:say("Another time, then.", cid)
                npcHandler.topic[cid] = 1
                return true
            end
            
            local missingItems = findMissingDeliveryItems(cid, chosenTask)
            if missingItems ~= "" then
                npcHandler:say("You are missing some items for the delivery. (missing: " .. missingItems .. ") Let me know when you want to {deliver} your task.", cid)
                npcHandler.topic[cid] = 1
                return true
            end
            removeDeliveryItems(cid, chosenTask)
            
            local rewardList = deliverRewards(cid, chosenTask)
            npcHandler:say("Thanks for the quick delivery! Here's your compensation.\n(" .. rewardList .. ")\nYou can choose a new {task} when you are ready.", cid)
            
            player:setStorageValue(taskStorages[1], -1)
            player:setStorageValue(taskStorages[2], -1)
            player:setStorageValue(taskStorages[3], -1)
            player:setStorageValue(taskStorages[4], -1)
            npcHandler.topic[cid] = 0
        
        end
    end
    
    
    return true
end

local function onAddFocus(cid)
    npcHandler.topic[cid] = 0
    taskReplies[cid] = {}
end

local function onReleaseFocus(cid)
    npcHandler.topic[cid] = 0
    taskReplies[cid] = {}
end

npcHandler:setCallback(CALLBACK_ONADDFOCUS, onAddFocus)
npcHandler:setCallback(CALLBACK_ONRELEASEFOCUS, onReleaseFocus)


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

Gamuza

Miembro
LV
7
 
Awards
4
Hola, una consulta, estuve intentando agregar este npc a mi servidor, pero mi servidor no tiene el archivo Npc.XML, y estuve intentando agregar la siguiente linea al inicio del lua.

Código:
local internalNpcName = "Taskman"
local npcType = Game.createNpcType(internalNpcName)
local npcConfig = {}

npcConfig.name = internalNpcName
npcConfig.description = internalNpcName

npcConfig.health = 100
npcConfig.maxHealth = npcConfig.health
npcConfig.walkInterval = 2000
npcConfig.walkRadius = 2

npcConfig.outfit = {
    lookType = 1210,
    lookHead = 79,
    lookBody = 79,
    lookLegs = 79,
    lookFeet = 79,
    lookAddons = 3
}

npcConfig.flags = {
    floorchange = false
}

Estoy recién familiarizándome con este mundo del lua y los Revscripts. y quería ver si me puedes guiar un poco a como configurar bien este script. saludos :D.
 

Alex

Miembro del equipo
Webdesigner
LV
58
 
Awards
38
Hola, una consulta, estuve intentando agregar este npc a mi servidor, pero mi servidor no tiene el archivo Npc.XML, y estuve intentando agregar la siguiente linea al inicio del lua.

Código:
local internalNpcName = "Taskman"
local npcType = Game.createNpcType(internalNpcName)
local npcConfig = {}

npcConfig.name = internalNpcName
npcConfig.description = internalNpcName

npcConfig.health = 100
npcConfig.maxHealth = npcConfig.health
npcConfig.walkInterval = 2000
npcConfig.walkRadius = 2

npcConfig.outfit = {
    lookType = 1210,
    lookHead = 79,
    lookBody = 79,
    lookLegs = 79,
    lookFeet = 79,
    lookAddons = 3
}

npcConfig.flags = {
    floorchange = false
}

Estoy recién familiarizándome con este mundo del lua y los Revscripts. y quería ver si me puedes guiar un poco a como configurar bien este script. saludos :D.
Hola,

El Npc.xml , aparte si compra/vende, siempre sera asi en los 12x hasta nuevo cambio:

Código:
<?xml version="1.0" encoding="UTF-8"?>
<npc name="Tarea" script="tarea.lua" walkinterval="2000" floorchange="0">
    <health now="100" max="100" />
    <look type="139" head="20" body="39" legs="45" feet="7" addons="0" />
</npc>

Luego dentro del script.lua que sera del NPC, es dependiendo de lo que hará el NPC, te aconsejo basarte en los NPC existentes, busca en el Tibia Official que NPC hace qué, y lo que estás buscando.
Por mi parte no soy scripter, pero consigo arreglar algunas cosas para que salgan cosas buenas.
 
Arriba