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

bestiary system tfs 1.5 by nekiro tibia 8.6

jareczekjsp

Member
Joined
Jan 30, 2023
Messages
264
Solutions
1
Reaction score
22
GitHub
Jarek123
Hello everyone I have problem I use script Bestiary chat sysyem and no working for me when I kill monster ,no see counts monster no reaction no errors in console


LUA:
-- Monster list with names
local monsters = {
    "Mega lord", "Mega demon", "Mega fury", "Mega grim reaper", "Mega hellhound", "Mega Medusa", "Megazord", "Mega serpent", "Mega orion", "Special haunter",
    "Bill Gates", "Deather", "Blue Djinn", "Bonebeast", "Bug", "Butterfly", "Butterfly Purple", "Butterfly Yellow",
    "Butterfly Red", "Butterfly Blue", "Carniphila", "Cave Rat", "Centipede", "Chicken", "Cobra", "Crab", "Crocodile",
    "Crypt Shambler", "Cyclops", "Dark Monk", "Deer", "Demon Skeleton", "Demon", "Dog", "Dragon Lord", "Dragon",
    "Dwarf Geomancer", "Dwarf Guard", "Dwarf Soldier", "Dwarf", "Dworc Fleshhunter", "Dworc Venomsniper", "Dworc Voodoomaster",
    "Efreet", "Elder Beholder", "Elephant", "Elf Arcanist", "Elf Scout", "Elf", "Fire Devil", "Fire Elemental",
    "Flamingo", "Frost Troll", "Gargoyle", "Gazer", "Ghost", "Ghoul", "Giant Spider", "Goblin", "Green Djinn",
    "Hero", "Hunter", "Hyaena", "Hydra", "Kongra", "Larva", "Lich", "Lion", "Lizard Sentinel", "Lizard Snakecharmer",
    "Lizard Templar", "Marid", "Merlkin", "Minotaur Archer", "Minotaur Guard", "Minotaur Mage", "Minotaur", "Monk",
    "Mummy", "Necromancer", "Orc Berserker", "Orc Leader", "Orc Rider", "Orc Shaman", "Orc Spearman", "Orc Warlord",
    "Orc Warrior", "Orc", "Panda", "Parrot", "Pig", "Poison Spider", "Polar Bear", "Priestess", "Rabbit", "Rat",
    "Rotworm", "Scarab", "Scorpion", "Serpent Spawn", "Sheep", "Sibang", "Skeleton", "Skunk", "Slime2", "Slime",
    "Smuggler", "Snake", "Spider", "Spit Nettle", "Stalker", "Stone Golem", "Swamp Troll", "Tarantula", "Terror Bird",
    "Tiger", "Troll", "Valkyrie", "Vampire", "War Wolf", "Warlock", "Wasp", "Wild Warrior", "Winter Wolf", "Witch",
    "Wolf", "Yeti"
}

-- Define the onKill function
function onKill(cid, target)
    local player = Player(cid)
    local targetName = getCreatureName(target)
    
    -- Check if the target is a monster
    if isMonster(target) then
        -- Find the index of the monster in the list
        local monsterIndex = -1
        for i, name in ipairs(monsters) do
            if name == targetName then
                monsterIndex = i
                break
            end
        end
        
        if monsterIndex ~= -1 then
            -- Use the monster index to set storage
            local key = 1010000 + monsterIndex
            local killCount = player:getStorageValue(key) or 0
            
            -- If the kill count is -1 or 0, set it to 1 instead of incrementing by 1
            if killCount <= 0 then
                killCount = 1
            else
                killCount = killCount + 1
            end
            
            player:setStorageValue(key, killCount)

local taskMessage = "[Bestiary] Total " .. targetName .. "s killed: " .. killCount .. "."
            sendChannelMessage(10, TALKTYPE_CHANNEL_O, taskMessage)

            -- Check if the killCount meets the requirement for the rewards
            if killCount % 100 == 0 then
                local maxHealth = target:getMaxHealth()
                local expReward = math.random(maxHealth*3, maxHealth * 7.25) -- Random experience reward based on monster's max health
                local goldReward = math.random(maxHealth*4, maxHealth * 7.25) -- Random gold reward based on monster's max health
                player:addExperience(expReward)
                player:addMoney(goldReward)
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have received a reward for killing " .. killCount .. " " .. targetName .. "s! Experience: " .. expReward .. ", Gold: " .. goldReward)
                
                -- Check if the kill count is also a multiple of 500 and give gem bag also!
                if killCount % 500 == 0 then
                    player:addItem(6512, 1) -- Add a gem bag
                    local expReward = math.random(maxHealth*7, maxHealth * 14.25) -- Random experience reward based on monster's max health
                    local goldReward = math.random(maxHealth*7, maxHealth * 14.25) -- Random gold reward based on monster's max health
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have received a Double reward for killing " .. killCount .. " " .. targetName .. "s! Experience: " .. expReward .. ", Gold: " .. goldReward)
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have received a gem bag as a reward for killing " .. killCount .. " " .. targetName .. "s!")
                end
            end
        else
            print("Monster not found in the list:", targetName)
        end
    end

    return true
end
 
make sure you have registered this event to player's (onLogin),

how to do this?

after line 21
write
LUA:
prnt("executed???")

try to kill a monster that its affected by this task system then check console.
 
I asked AI for help to create a bestiary system similar to the one in the post... I'm quite inexperienced with scripting, so this is a request for someone who has the knowledge — please tell me if it's a viable system, if it has flaws, or if it's something valid?? Thank youuu!

LUA:
local bestiarySystem = {
    monsters = {
        -- Sua lista de monstros aqui
        "Dragon", "Dragon Lord", "Demon", -- etc...
    },
   
    config = {
        storageBase = 1010000,         -- Base para storages
        maxKills = 2000,               -- Limite máximo
        smallRewardInterval = 200,     -- Recompensa a cada 200 kills
        mediumRewardInterval = 500,    -- Recompensa melhor a cada 500 kills
       
        -- Recompensas pequenas (a cada 200)
        smallReward = {
            expMultiplier = {min = 1.5, max = 3},   -- 1.5x a 3x o HP do monstro
            goldMultiplier = {min = 1, max = 2}     -- 1x a 2x o HP do monstro
        },
       
        -- Recompensas médias (a cada 500)
        mediumReward = {
            expMultiplier = {min = 3, max = 5},
            goldMultiplier = {min = 2, max = 4},
            items = {
                {id = 2148, count = 50, chance = 100},     -- 50 gold coins (100%)
                {id = 2152, count = 5, chance = 50},       -- 5 platinum coins (50%)
                {id = 2160, count = 1, chance = 10}        -- 1 crystal coin (10%)
            }
        },
       
        -- Recompensa final (ao completar 2000)
        finalReward = {
            message = "You have completed the %s bestiary!",
            items = {
                {id = 2160, count = 5},                   -- 5 crystal coins
                {id = 6512, count = 1}                     -- 1 gem bag
            }
        },
       
        channelId = 10,
        channelTalkType = TALKTYPE_CHANNEL_O
    },
   
    monsterIndexCache = {}
}

-- Inicializar cache de monstros
for index, name in ipairs(bestiarySystem.monsters) do
    bestiarySystem.monsterIndexCache[name:lower()] = index
end

-- Funções auxiliares
local function getMonsterIndex(monsterName)
    return bestiarySystem.monsterIndexCache[monsterName:lower()]
end

local function calculateReward(maxHealth, multiplier)
    return math.random(maxHealth * multiplier.min, maxHealth * multiplier.max)
end

local function giveRandomItems(player, itemsTable)
    for _, item in ipairs(itemsTable) do
        if math.random(100) <= (item.chance or 100) then
            player:addItem(item.id, item.count or 1)
        end
    end
end

-- Função principal
local function onKill(creature, target)
    local player = Player(creature)
    if not player or not target:isMonster() then
        return true
    end

    local targetName = target:getName()
    local monsterIndex = getMonsterIndex(targetName)
    if not monsterIndex then
        return true
    end

    local storageKey = bestiarySystem.config.storageBase + monsterIndex
    local killCount = player:getStorageValue(storageKey)
   
    -- Verificar se já completou
    if killCount >= bestiarySystem.config.maxKills then
        return true
    end

    -- Atualizar contagem
    killCount = killCount + 1
    player:setStorageValue(storageKey, killCount)

player:sendTextMessage(MESSAGE_STATUS_DEFAULT, string.format("[Bestiary] %s: %d/%d", targetName, killCount, bestiarySystem.config.maxKills))


    local maxHealth = target:getMaxHealth()
    local config = bestiarySystem.config

    -- Recompensa a cada 200 kills
    if killCount % config.smallRewardInterval == 0 then
        local exp = calculateReward(maxHealth, config.smallReward.expMultiplier)
        local gold = calculateReward(maxHealth, config.smallReward.goldMultiplier)
       
        player:addExperience(exp)
        player:addMoney(gold)
        player:sendTextMessage(MESSAGE_INFO_DESCR,
            string.format("Bestiary reward: %d XP and %d gold for killing %d %ss!",
            exp, gold, killCount, targetName))
    end

    -- Recompensa melhor a cada 500 kills
    if killCount % config.mediumRewardInterval == 0 then
        local exp = calculateReward(maxHealth, config.mediumReward.expMultiplier)
        local gold = calculateReward(maxHealth, config.mediumReward.goldMultiplier)
       
        player:addExperience(exp)
        player:addMoney(gold)
        giveRandomItems(player, config.mediumReward.items)
       
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE,
            string.format("Medium bestiary reward: %d XP, %d gold and items for %d %ss!",
            exp, gold, killCount, targetName))
    end

    -- Recompensa final ao completar
    if killCount == config.maxKills then
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE,
            string.format(config.finalReward.message, targetName))
       
        for _, item in ipairs(config.finalReward.items) do
            player:addItem(item.id, item.count)
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE,
                string.format("Received %d %s as final reward!",
                item.count, ItemType(item.id):getName()))
        end
    end

    return true
end

-- Registrar eventos
local creatureEvent = CreatureEvent("BestiarySystem")
function creatureEvent.onKill(player, target)
    return onKill(player, target)
end
creatureEvent:register()

local loginEvent = CreatureEvent("BestiaryLogin")
function loginEvent.onLogin(player)
    player:registerEvent("BestiarySystem")
    return true
end
loginEvent:type("login")
loginEvent:register()
 
Last edited:
Hello everyone I have problem I use script Bestiary chat sysyem and no working for me when I kill monster ,no see counts monster no reaction no errors in console
(not windows)
all names of the monsters xml must be the same as the script, the system differentiates between upper and lower case.
 
I managed to improve the system and tested it... everything is working perfectly...


The bestiary is like a task, but it's a task that starts automatically haha, and it gives rewards at different stages...


Here’s an example: with 5,000 monsters you get the 1st reward, at 10,000 the 2nd reward, and finally at 20,000 the last reward... easy to configure...





local bestiarySystem = {
monsters = {
-- Custom GPT
"Abyssal Devourer", "Zarkhan", "Nyxaroth",

-- Custom News
"Trolling", "Revenger", "Cronda", "Behewarrior", "Behesoldier",
"Nature", "Frazzlemaw", "Guzzlemaw", "Haunted Dragon", "Demoniac",
"Rei da Guerra",

-- Custom Drakens
"Draken Abomination", "Draken Spellweaver", "Draken Warmaster",

-- Custom Others
"Medusa", "Frost Gianter", "Dragon King", "Infernalist",
"Grim Reaper", "Black Demon",

-- Asuras
"Dawnfire Asura", "Midnight Asura", "Falcon knight", "falcon Paladin",

-- Arachnids
"Giant Spider",

-- Demons
"Demon", "Fury", "Juggernaut", "Nightmare", "Plaguesmith",

-- Dragons
"Dragon Lord", "Dragon", "Frost Dragon", "Rotworm",

-- Dwarves
"Dwarf Guard", "Dwarf Soldier", "Dwarf",

-- Giants
"Behemoth", "Cyclops",

-- Minotaurs
"Minotaur Archer", "Minotaur Guard", "Minotaur Mage", "Minotaur",

-- Misc Reptiles
"Hydra",

-- Necromancers
"Necromancer",

-- Outlaws
"Black Knight", "Hero",

-- Serpents
"Cobra", "Serpent Spawn", "Snake",

-- Sorcerers
"Warlock",

-- Vampires
"Vampire"
},

config = {
storageBase = 1010000, -- Base para storages
maxKills = 20000, -- Limite máximo
smallRewardInterval = 5000, -- Recompensa 5000 kills
mediumRewardInterval = 10000, -- Recompensa melhor 10000 kills

-- Recompensas pequenas
smallReward = {
items = {
{id = 2160, count = 25, chance = 100}, -- 25 crystal coin (100%)
{id = 7630, count = 10, chance = 100}, -- 10 forgott token (100%)
{id = 7665, count = 1, chance = 60}, -- 1 stamina refil de 5 horas (60%)
{id = 7507, count = 1, chance = 20} -- 1 roulet token (20%)
}
},

-- Recompensas médias
mediumReward = {
items = {
{id = 2160, count = 25, chance = 100}, -- 25 crystal coins (100%)
{id = 7630, count = 20, chance = 100}, -- 20 forgott token (100%)
{id = 7665, count = 1, chance = 80}, -- 1 stamina refil de 5 horas (80%)
{id = 7507, count = 1, chance = 50} -- 1 roulet token (50%)
}
},

-- Recompensa final
finalReward = {
message = "You have completed the %s bestiary!",
items = {
{id = 2160, count = 25, chance = 100}, -- 25 crystal coins (100%)
{id = 7630, count = 20, chance = 100}, -- 20 forgott token (100%)
{id = 7665, count = 1, chance = 100}, -- 1 stamina refil de 5 horas (100%)
{id = 7507, count = 1, chance = 100} -- 1 roulet token (100%)
}
},

channelId = 10,
channelTalkType = TALKTYPE_CHANNEL_O
},

monsterIndexCache = {}
}

-- Inicializar cache de monstros
for index, name in ipairs(bestiarySystem.monsters) do
bestiarySystem.monsterIndexCache[name:lower()] = index
end

-- Funções auxiliares
local function getMonsterIndex(monsterName)
return bestiarySystem.monsterIndexCache[monsterName:lower()]
end

local function giveRandomItems(player, itemsTable)
for _, item in ipairs(itemsTable) do
if math.random(100) <= (item.chance or 100) then
player:addItem(item.id, item.count or 1)
end
end
end

-- Função principal corrigida
local function onKill(creature, target)
local player = Player(creature)
if not player or not target:isMonster() then
return true
end

local targetName = target:getName()
local monsterIndex = getMonsterIndex(targetName)
if not monsterIndex then
return true
end

local storageKey = bestiarySystem.config.storageBase + monsterIndex
local killCount = player:getStorageValue(storageKey)

-- Verificar se já completou
if killCount >= bestiarySystem.config.maxKills then
return true
end

-- Atualizar contagem (tratando caso de storage não existente)
killCount = (killCount == -1 and 1 or killCount + 1)
player:setStorageValue(storageKey, killCount)

-- Mensagem normal de progresso
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, string.format("[Bestiary] %s: %d/%d", targetName, killCount, bestiarySystem.config.maxKills))

local config = bestiarySystem.config

-- Recompensa a cada 1000 kills (apenas quando killCount for múltiplo exato)
if killCount > 0 and killCount % config.smallRewardInterval == 0 then
giveRandomItems(player, config.smallReward.items)
player:sendTextMessage(MESSAGE_INFO_DESCR,
string.format("Bestiary reward: items for killing %d %ss!",
killCount, targetName))
end

-- Recompensa melhor a cada 2000 kills (apenas quando killCount for múltiplo exato)
if killCount > 0 and killCount % config.mediumRewardInterval == 0 then
-- Não dar a recompensa small se for também medium
if killCount % config.smallRewardInterval ~= 0 or config.smallRewardInterval == config.mediumRewardInterval then
giveRandomItems(player, config.mediumReward.items)
player:sendTextMessage(MESSAGE_EVENT_ADVANCE,
string.format("Medium bestiary reward: items for %d %ss!",
killCount, targetName))
end
end

-- Recompensa final ao completar
if killCount == config.maxKills then
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE,
string.format(config.finalReward.message, targetName))

for _, item in ipairs(config.finalReward.items) do
player:addItem(item.id, item.count)
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE,
string.format("Received %d %s as final reward!",
item.count, ItemType(item.id):getName()))
end
end

return true
end

-- Registrar eventos
local creatureEvent = CreatureEvent("BestiarySystem")
function creatureEvent.onKill(player, target)
return onKill(player, target)
end
creatureEvent:register()

local loginEvent = CreatureEvent("BestiaryLogin")
function loginEvent.onLogin(player)
player:registerEvent("BestiarySystem")
return true
end
loginEvent:type("login")
loginEvent:register()
 
Back
Top