• 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 doubt about reward for killing monters not npc

Thorn

Spriting since 2013
Joined
Sep 24, 2012
Messages
2,203
Solutions
1
Reaction score
922
Location
Chile
Hello guys, i have read and searched for a long time now so i ask here:
is it possible to have something that will give players a reward (item) after killing a x number of a monster? but without a npc?
i mean like whe you get to lvl 100 you get a reward, but here you have killed 100 demons and you get a reward.
is it possible? if so, is this script around? i haven't seen anything like this, al have a npc giving task
 
Solution
I know it's "solved", but I cant accept this script as the accepted solution, also you could just ask me on discord for this.

Code:
-- script written by Nekiro#5727
local config = {
    {amount = 2, monsters = {"rat", "cave rat"}, rewards = {{2160, 1}, {2152, 1}}, storage = 9999},
    {amount = 5, monsters = {"goblin", "skeleton"}, rewards = {{2160, 1}, {2152, 1}}, storage = 10001},
    {amount = 3, monsters = {"ghoul", "demon skeleton"}, rewards = {{2160, 1}, {2152, 1}}, storage = 10002},
    {amount = 7, monsters = {"dragon"}, rewards = {{2160, 1}, {2152, 1}}, storage = 10003},
}

local function getConfigTable(monsterName)
    for _, entry in pairs(config) do
        if table.contains(entry.monsters, monsterName) then
            return...
creaturescript, onkill? what tfs?
I guess that he wants creaturescript with onAdvance(to give reward at lvl 100) and onKill (to give reward when the player kill 100 monsters)
is just a storage counter how much monsters the player had killed, if the number is >= 100 then give reward to player
 
creaturescript, onkill? what tfs?
tfs 1.0
so it's possible? :O

I guess that he wants creaturescript with onAdvance(to give reward at lvl 100) and onKill (to give reward when the player kill 100 monsters)
is just a storage counter how much monsters the player had killed, if the number is >= 100 then give reward to player

just onkill :P wanted to know if it's possible, and if there's any script like that around here
 
ofc is possible
Code:
function onKill(creature, target)
    local targetMonster = target:getMonster()
    if not targetMonster then
        return true
    end

    if targetMonster:getName():lower() ~= 'your monster(s)' then
        return true
    end

    local player = creature:getPlayer()
    local storage = player:getStorageValue(Storage.MonsterCounter)
    if storage >= 100 then
        player:addItem(rewardid, count)
     
    end
    player:setStorageValue(Storage.MonsterCounter, player:getStorageValue(Storage.MonsterCounter) + 1)
    return true
end
also, you need register this event in login.lua to it work correctly
 
Last edited:
ofc is possible
Code:
function onKill(creature, target)
    local targetMonster = target:getMonster()
    if not targetMonster then
        return true
    end

    if targetMonster:getName():lower() ~= 'your monster(s)' then
        return true
    end

    local player = creature:getPlayer()
    local storage = player:getStorageValue(Storage.MonsterCounter)
    if storage >= 100 then
        player:addItem(rewardid, count)
     
    end
    player:setStorageValue(player:getStorageValue(Storage.MonsterCounter) + 1)
    return true
end
also, you need register this event in login.lua to it work correctly

Tell me if I am wrong, but won't this give the reward every single time you kill a monster after 100?

I believe to just give the reward once you would want to change "if storage >= 100 then" to "if storage == 100 then".
 
Tell me if I am wrong, but won't this give the reward every single time you kill a monster after 100?

I believe to just give the reward once you would want to change "if storage >= 100 then" to "if storage == 100 then".
yeah, you're correct, just a mess with ">" cuz I took this script somewhere, sry boss
but, then...
Code:
function onKill(creature, target)
    local targetMonster = target:getMonster()
    if not targetMonster then
        return true
    end

    if targetMonster:getName():lower() ~= 'your monster(s)' then
        return true
    end

    local player = creature:getPlayer()
    local storage = player:getStorageValue(Storage.MonsterCounter)
    if storage >= 100 then
        player:addItem(rewardid, count)
        player:setStorageValue(Storage.MonsterCounter, 0)
    end
    player:setStorageValue(Storage.MonsterCounter, player:getStorageValue(Storage.MonsterCounter) + 1)
    return true
end
also I fixed the line that set storages to the player...
also another thing with Storage.MonsterCounter, I use it because all my storages are saved in the lib/somefolder/storages.lua
 
yeah, you're correct, just a mess with ">" cuz I took this script somewhere, sry boss
but, then...
Code:
function onKill(creature, target)
    local targetMonster = target:getMonster()
    if not targetMonster then
        return true
    end

    if targetMonster:getName():lower() ~= 'your monster(s)' then
        return true
    end

    local player = creature:getPlayer()
    local storage = player:getStorageValue(Storage.MonsterCounter)
    if storage >= 100 then
        player:addItem(rewardid, count)
        player:setStorageValue(Storage.MonsterCounter, 0)
    end
    player:setStorageValue(Storage.MonsterCounter, player:getStorageValue(Storage.MonsterCounter) + 1)
    return true
end
also I fixed the line that set storages to the player...
also another thing with Storage.MonsterCounter, I use it because all my storages are saved in the lib/somefolder/storages.lua
I dont know if TFS 1.0 default storage value is -1 if so then you could add this to the code aswell
Code:
if player:getStorageValue(Storage.MonsterCounter) < 0 or player:getStorageValue(Storage.MonsterCounter) == nil then
   player:setStorageValue(Storage.MonsterCounter, 0)
end
 
yeah, you're correct, just a mess with ">" cuz I took this script somewhere, sry boss
but, then...
Code:
function onKill(creature, target)
    local targetMonster = target:getMonster()
    if not targetMonster then
        return true
    end

    if targetMonster:getName():lower() ~= 'your monster(s)' then
        return true
    end

    local player = creature:getPlayer()
    local storage = player:getStorageValue(Storage.MonsterCounter)
    if storage >= 100 then
        player:addItem(rewardid, count)
        player:setStorageValue(Storage.MonsterCounter, 0)
    end
    player:setStorageValue(Storage.MonsterCounter, player:getStorageValue(Storage.MonsterCounter) + 1)
    return true
end
also I fixed the line that set storages to the player...
also another thing with Storage.MonsterCounter, I use it because all my storages are saved in the lib/somefolder/storages.lua
wow this is awesome thank you!! could i bother you with 1 little thing? can you make it so i can put many monsters? like group A(100 demon, 20 rat, 2 skeleton)= reward A
group B (10 hero, 150 demon, 20 skeleton)=reward B?

if it's too much of a trouble don't worry
 
wow this is awesome thank you!! could i bother you with 1 little thing? can you make it so i can put many monsters? like group A(100 demon, 20 rat, 2 skeleton)= reward A
group B (10 hero, 150 demon, 20 skeleton)=reward B?

if it's too much of a trouble don't worry
you can test it:
Code:
local monsters = {
    ['Rat'] = {reward = itemid, reward2 = itemid, amountToKill = 100, storage = storageValue, storage = 123},
    ['Demon'] = {reward = itemid, reward2 = itemid, amountToKill = 100, storage = 1234},
    ['Dragon'] = {reward = itemid, reward2 = itemid, amountToKill = 100, storage = 12345},
    ['Hydra'] = {reward = itemid, reward2 = itemid, amountToKill = 100, storage = 54332},
    ['Dragon Lord'] = {reward = itemid, reward2 = itemid, amountToKill = 100, storage = 1233},
    ['Medusa'] = {reward = itemid, reward2 = itemid, amountToKill = 100, storage = 45654},
    ['Mutated Rat'] = {reward = itemid, reward2 = itemid, amountToKill = 100, storage = 123123}
}
function onKill(creature, target)
    local targetMonster = target:getMonster()
    if not targetMonster then
        return true
    end

    local monster = monsters[target:getName():lower()]
    if not monster then
        return true
    end

    local player = creature:getPlayer()
    local storage = player:getStorageValue(monster.storage)
    if storage < 0 or storage == nil then
        player:setStorageValue(storage, 0)
    end
    if storage >= monster.amountToKill then
        player:addItem(monster.reward, count)
        if monster.reward2 then
            player:addItem(monster.reward2, count)
        end
        player:setStorageValue(storage, 0)
    end
    player:setStorageValue(storage, player:getStorageValue(storage) + 1)
    return true
end
 
LUA:
local groups = {
[1] = {monsters = {
        [1] = {name = "rat", storage = 10000, amount = 50},
        [2] = {name = "troll", storage = 10000, amount = 50}
        },
        rewards = {
        [1] = {itemid = 1111, amount = 1},
        [2] = {itemid = 1111, amount = 1}
        }
        storage = 11000,
        msg = "You have killed xx and recieved xx."
        } -- Add more groups here

}

function onKill(creature, target)
 player = Player(creature)

 if not player then return true end

    for i = 1, #groups do
        if player:getStorageValue(groups[i].storage) == nil or player:getStorageValue(groups[i].storage) == -1 then
            has_killed_monsters = true
                for i = 1, #groups[i].monsters do
                    if player:getStorageValue(groups[i].monsters[i].storage) < groups[i].monsters[i].amount then
                        has_killed_monsters = false
                        break
                    end
                end
               
                if has_killed_monsters == true then
                    for i = 1, #groups[i].rewards do
                        player:addItem(groups[i].rewards[i].itemid, groups[i].rewards[i].amount)
                    end
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, groups[i].msg)
                    player:setStorageValue(groups[i].storage, 1)
                end
        end
    end
return true
end
 
Last edited:
LUA:
local groups = {
[1] = {monsters = {
        [1] = {name = "rat", storage = 10000, amount = 50},
        [2] = {name = "troll", storage = 10000, amount = 50}
        },
        rewards = {
        [1] = {itemid = 1111, amount = 1},
        [2] = {itemid = 1111, amount = 1}
        }
        storage = 11000,
        msg = "You have killed xx and recieved xx."
        } -- Add more groups here

}

function onKill(creature, target)
 player = Player(creature)

 if not player then return true end

    for i = 1, #groups do
        if player:getStorageValue(groups[i].storage) == nil or player:getStorageValue(groups[i].storage) == -1 then
            has_killed_monsters = true
                for i = 1, #groups[i].monsters do
                    if player:getStorageValue(groups[i].monsters[i].storage) < groups[i].monsters[i].amount then
                        has_killed_monsters = false
                        break
                    end
                end
             
                if has_killed_monsters == true then
                    for i = 1, #groups[i].rewards do
                        player:addItem(groups[i].rewards[i].itemid, groups[i].rewards[i].amount)
                    end
                    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, groups[i].msg)
                    player:setStorageValue(groups[i].storage, 1)
                end
        end
    end
return true
end
I haven't looked over all your code but why did you use an explicit index and then a property index for the groups table? Also when it isn't exactly clear the intentions you should comment the code. Thanks.
 
I know it's "solved", but I cant accept this script as the accepted solution, also you could just ask me on discord for this.

Code:
-- script written by Nekiro#5727
local config = {
    {amount = 2, monsters = {"rat", "cave rat"}, rewards = {{2160, 1}, {2152, 1}}, storage = 9999},
    {amount = 5, monsters = {"goblin", "skeleton"}, rewards = {{2160, 1}, {2152, 1}}, storage = 10001},
    {amount = 3, monsters = {"ghoul", "demon skeleton"}, rewards = {{2160, 1}, {2152, 1}}, storage = 10002},
    {amount = 7, monsters = {"dragon"}, rewards = {{2160, 1}, {2152, 1}}, storage = 10003},
}

local function getConfigTable(monsterName)
    for _, entry in pairs(config) do
        if table.contains(entry.monsters, monsterName) then
            return entry
        end
    end
    return false
end

function onKill(creature, target)
    if not target:isMonster() or target:getMaster() then
        return true
    end

    local player = creature:getPlayer()
    if not player then
        return true
    end

    local table = getConfigTable(target:getName():lower())
    if not table then
        return true
    end

    if player:getStorageValue(table.storage) < 0 then -- if config storages are predefined you should actually make this in login.lua, because it will check for that for every monster killed.
        player:setStorageValue(table.storage, 0)
    end

    if player:getStorageValue(table.storage) >= table.amount then
        for _, item in pairs(table.rewards) do
            player:addItem(item[1], item[2])
        end
        player:setStorageValue(table.storage, 0)
        return true
    end

    player:setStorageValue(table.storage, player:getStorageValue(table.storage) + 1)
    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You killed ".. player:getStorageValue(table.storage) .. "/".. table.amount .." monsters in your current task: ".. table.concat(table.monsters, ", ") .. ".")
    return true
end
@edit forgot about one thing, just edited the code.

This is the 2nd version of this script with changes Thorn requested.
Code:
-- script written by Nekiro#5727
local config = {
    {
        amount = 150,
        monsters = {"demon"},
        rewards = {
            [1] = {{"crystal coin", 5}, {"platinum coin", 5}}, -- [amount of kills] = {item name, item count}
            [3] = {{"crystal coin", 10}, {"platinum coin", 10}},
            [5] = {{"crystal coin", 50}, {"platinum coin", 50}},
        },
        storage = 99099
    },
}

local function getConfigTable(monsterName)
    for _, entry in pairs(config) do
        if table.contains(entry.monsters, monsterName) then
            return entry
        end
    end
    return false
end

function onKill(creature, target)
    if not target:isMonster() or target:getMaster() then
        return true
    end

    local player = creature:getPlayer()
    if not player then
        return true
    end

    local table = getConfigTable(target:getName():lower())
    if not table then
        return true
    end

    if player:getStorageValue(table.storage) < 0 then -- if config storages are predefined you should actually make this in login.lua, because it will check for that for every monster killed.
        player:setStorageValue(table.storage, 0)
    end

    if player:getStorageValue(table.storage) >= table.amount then -- task is already at the max number (config.amount), we do not count the kills, so we can terminate the script right away.
        return true
    end

    player:setStorageValue(table.storage, player:getStorageValue(table.storage) + 1)

    local rewards = table.rewards[player:getStorageValue(table.storage)]
    if rewards then
        for _, item in pairs(rewards) do
            player:addItem(ItemType(item[1]):getId(), item[2])
        end
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Congratulations, you have finished the task, here is your reward!")
    end
    return true
end


I didn't test this script, but it should work fine, let me know.
 
Last edited:
Solution
I haven't looked over all your code but why did you use an explicit index and then a property index for the groups table? Also when it isn't exactly clear the intentions you should comment the code. Thanks.

I did it so he could have multiple groups of monsters, for example. He could do a group thats required 10 rats, 15 troll he can make another group that does 15 dragons 30 dragon lords, 30 demons, 10 morgaroths, ect. ect. He can have as many groups as he wants and its easily configurable all with their own separate rewards. He just has to add another group which the next one would be group [2].


I know it's "solved", but I cant accept this script as the accepted solution, also you could just ask me on discord for this.

Code:
-- script written by Nekiro#5727
local config = {
    {amount = 2, monsters = {"rat", "cave rat"}, rewards = {{2160, 1}, {2152, 1}}, storage = 9999},
    {amount = 5, monsters = {"goblin", "skeleton"}, rewards = {{2160, 1}, {2152, 1}}, storage = 10001},
    {amount = 3, monsters = {"ghoul", "demon skeleton"}, rewards = {{2160, 1}, {2152, 1}}, storage = 10002},
    {amount = 7, monsters = {"dragon"}, rewards = {{2160, 1}, {2152, 1}}, storage = 10003},
}

local function getConfigTable(monsterName)
    for _, entry in pairs(config) do
        if table.contains(entry.monsters, monsterName) then
            return entry
        end
    end
    return false
end

function onKill(creature, target)
    if not target:isMonster() or target:getMaster() then
        return true
    end

    local player = creature:getPlayer()
    if not player then
        return true
    end

    local table = getConfigTable(target:getName():lower())
    if not table then
        return true
    end

    if player:getStorageValue(table.storage) < 0 then -- if config storages are predefined you should actually make this in login.lua, because it will check for that for every monster killed.
        player:setStorageValue(table.storage, 0)
    end

    if player:getStorageValue(table.storage) >= table.amount then
        for _, item in pairs(table.rewards) do
            player:addItem(item[1], item[2])
        end
        player:setStorageValue(table.storage, 0)
        return true
    end

    player:setStorageValue(table.storage, player:getStorageValue(table.storage) + 1)
    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You killed ".. player:getStorageValue(table.storage) .. "/".. table.amount .." monsters in your current task: ".. table.concat(table.monsters, ", ") .. ".")
    return true
end
@edit forgot about one thing, just edited the code.

This is the 2nd version of this script with changes Thorn requested.
Code:
-- script written by Nekiro#5727
local config = {
    {
        amount = 150,
        monsters = {"demon"},
        rewards = {
            [1] = {{"crystal coin", 5}, {"platinum coin", 5}}, -- [amount of kills] = {item name, item count}
            [3] = {{"crystal coin", 10}, {"platinum coin", 10}},
            [5] = {{"crystal coin", 50}, {"platinum coin", 50}},
        },
        storage = 99099
    },
}

local function getConfigTable(monsterName)
    for _, entry in pairs(config) do
        if table.contains(entry.monsters, monsterName) then
            return entry
        end
    end
    return false
end

function onKill(creature, target)
    if not target:isMonster() or target:getMaster() then
        return true
    end

    local player = creature:getPlayer()
    if not player then
        return true
    end

    local table = getConfigTable(target:getName():lower())
    if not table then
        return true
    end

    if player:getStorageValue(table.storage) < 0 then -- if config storages are predefined you should actually make this in login.lua, because it will check for that for every monster killed.
        player:setStorageValue(table.storage, 0)
    end

    if player:getStorageValue(table.storage) >= table.amount then -- task is already at the max number (config.amount), we do not count the kills, so we can terminate the script right away.
        return true
    end

    player:setStorageValue(table.storage, player:getStorageValue(table.storage) + 1)

    local rewards = table.rewards[player:getStorageValue(table.storage)]
    if rewards then
        for _, item in pairs(rewards) do
            player:addItem(ItemType(item[1]):getId(), item[2])
        end
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Congratulations, you have finished the task, here is your reward!")
    end
    return true
end


I didn't test this script, but it should work fine, let me know.

This is a lot of code for less then what I made.
 
I did it so he could have multiple groups of monsters, for example. He could do a group thats required 10 rats, 15 troll he can make another group that does 15 dragons 30 dragon lords, 30 demons, 10 morgaroths, ect. ect. He can have as many groups as he wants and its easily configurable all with their own separate rewards. He just has to add another group which the next one would be group [2].




This is a lot of code for less then what I made.
No, it’s not and there is actually difference, my script works. Btw. fix your tabbing and declarations.
 
Everyone has their preferences on how they would write this code, no reason to be an ass (and yes, many times people put up code with a bug or two in it, I often have bugs in my first writing of a code). No need to argue or throw shade at each other.

I was just thinking of putting my own code, but I use TFS 0.X not TFS 1.X mostly. Which is why I haven't been helping on the forums lately. I just don't like TFS 1.X lol.
 
Back
Top