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

Tfs 1.4 / 1.5 "lottery" script

Mr Noxi

Noxus Otserver
Joined
May 13, 2010
Messages
272
Solutions
3
Reaction score
94
Location
Sweden
Hey

So i got this scrip that req a key to get a random reward but its messing up with the chancec of what item to give the player.

As can be seen below, i made it from top to bottom but the item at bottom has chance = 1000 witch should be 100% but i never get that item, am more likely to get other stuff.

Why is that ?

Lua:
local config = {
    actionId = 45055, -- ID on chest
    cooldown = {
        key = 13292,
    },
    rewards = {
        {itemId = 2160, minCount = 10, maxCount = 30, chance = 100},  -- CC
        {itemId = 26412, minCount = 1, maxCount = 5, chance = 200}, -- token
        {itemId = 26413, minCount = 1, maxCount = 3, chance = 300}, -- token 2
        {itemId = 20138, minCount = 1, maxCount = 1, chance = 400}, -- Endengered leech
        {itemId = 2500, minCount = 1, maxCount = 1, chance = 500}, -- Amazon Armor
        {itemId = 8865, minCount = 1, maxCount = 1, chance = 600}, -- Dark lord's cape
        {itemId = 8189, minCount = 1, maxCount = 1, chance = 700}, -- Exp scroll
        {itemId = 2345, minCount = 1, maxCount = 1, chance = 1000} -- Global Exp scroll
       
       
       
    }
}

local rewardChest = Action()

function rewardChest.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local rewardList = {} -- this section is forcing a single item to be chosen from the rewards section
    while #rewardList < 1 do
        for i = 1, #config.rewards do
            rand = math.random(1000)
            if rand <= config.rewards[i].chance then
                rewardList[#rewardList + 1] = i
            end
        end
    end
    if player:getItemCount(13292) > 0 then
    rand = math.random(#rewardList)
    player:removeItem(13292,1)
    player:addItem(config.rewards[rand].itemId, math.random(config.rewards[rand].minCount, config.rewards[rand].maxCount), true)
    player:say("Received " .. ItemType(config.rewards[rand].itemId):getName():lower() .. " as reward.", TALKTYPE_MONSTER_SAY)
    doSendMagicEffect(player:getPosition(), CONST_ME_HOLYAREA)
    else
    player:say("You need a magical delux key!", TALKTYPE_MONSTER_SAY)
    return true
    end
end

rewardChest:aid(config.actionId)
rewardChest:register()
 
Lua:
local config = {
    actionId = 45001, -- ID on chest
    cooldown = {
        
        key = 8978,
        
    },
    rewards = {
        {itemId = 2148, minCount = 1, maxCount = 1, chance1 = 1000, chance2=1},
        {itemId = 2149, minCount = 1, maxCount = 1, chance1 = 5999, chance2=1001},
        {itemId = 2152, minCount = 1, maxCount = 1, chance1 = 7000, chance2=6000},
        {itemId = 10559, minCount = 1, maxCount = 1, chance1 = 8000, chance2=7001},
        {itemId = 10555, minCount = 1, maxCount = 1, chance1 = 9000, chance2=8001},
        {itemId = 10556, minCount = 1, maxCount = 1, chance1 = 9500, chance2=9001},
        {itemId = 10557, minCount = 1, maxCount = 1, chance1 = 9510, chance2=9501},
        {itemId = 10558, minCount = 1, maxCount = 1, chance1 = 10000, chance2=9511}   
    }
}

local rewardChest = Action()

function rewardChest.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local rewardList = {} -- this section is forcing a single item to be chosen from the rewards section
    g = 0 -- this will store our reward, g= 1 first item, g=2 second item etc.

    --while #rewardList <= #config.rewards do
    rand = math.random(10000)
    print(rand)
        for i = 1, #config.rewards do
            --if (rand >= config.rewards[1].chance1 or rand <= config.rewards[i].chance2 and rand <= config.rewards[i].chance1) then
            if rand >= config.rewards[i].chance1 or rand <= config.rewards[i].chance1 and rand >= config.rewards[i].chance2 then
            --rewardList[#rewardList + i] = i
            g = g + 1
            end
        end
    if g == 0 then --to avoid g=0
    g = 1
    end   

    ---print(g)
    --end
    if player:getItemCount(8978) > 0 then
    rand = g
    --print(#rewardList)
    --print (rewardList[#rewardList])
    player:removeItem(8978,1)
    player:addItem(config.rewards[rand].itemId, math.random(config.rewards[rand].minCount, config.rewards[rand].maxCount), true)
    player:say("Received " .. ItemType(config.rewards[rand].itemId):getName():lower() .. " as reward.", TALKTYPE_MONSTER_SAY)
    doSendMagicEffect(player:getPosition(), CONST_ME_HOLYAREA)
    else
    player:say("You need a key!", TALKTYPE_MONSTER_SAY)
    return true
    end
end

rewardChest:aid(config.actionId)
rewardChest:register()
Post automatically merged:

The code is not optimized, but it is working at least :)
 
When I made that script for someone..
The idea was to get a single item.

It cycles through the list, using the chance of the items to create a secondary list of items..
At which point it chooses a single item, and gives it to the player.

The 'deluxe key' requirement was added somewhere later along the line.. because I'd never add it in like that. lol

Pretty sure there was a 20 hour cooldown on the chest as well.. which seems to of been removed.

People are strange. 🤷‍♂️

--
So tldr, the 1000 chance you added to the experience scroll, only guarantee's that it get's into the final item lottery.
It doesn't guarantee that it will be given to the player.
 
When I made that script for someone..
The idea was to get a single item.

It cycles through the list, using the chance of the items to create a secondary list of items..
At which point it chooses a single item, and gives it to the player.

The 'deluxe key' requirement was added somewhere later along the line.. because I'd never add it in like that. lol

Pretty sure there was a 20 hour cooldown on the chest as well.. which seems to of been removed.

People are strange. 🤷‍♂️

--
So tldr, the 1000 chance you added to the experience scroll, only guarantee's that it get's into the final item lottery.
It doesn't guarantee that it will be given to the player.
Do you see anything wrong with my version? I know I could clean it up a lot but anything else?
The intended purpose would be: player has key> player can open chest and get a random reward.
The probability for a given item would be: (chance1-chance2)/10000. This way you can weigh the probabilities of certain items instead of having all items have the same chance to get picked. I am new, so any feedback is appreciated :)
 
Do you see anything wrong with my version? I know I could clean it up a lot but anything else?
The intended purpose would be: player has key> player can open chest and get a random reward.
The probability for a given item would be: (chance1-chance2)/10000. This way you can weigh the probabilities of certain items instead of having all items have the same chance to get picked. I am new, so any feedback is appreciated :)
It depends on the goal.

In my way, the goal is to give the player a single item.
The chances for each item are out of 1000. (So from 100% to 0.1%)

All items are rolled for their chance to be given to the player.
The items that win the initial lottery are pooled together.
Of the items that 'won' their chance, 1 of those items is given to the player, at random.

In this way, the lottery is created, and is easy to setup and can add/remove items, while maintaining a specified chance per item.

All items get their fair chance in the initial lottery.
The secondary lottery, where a single item is chosen at random, does not affect the odds of the player receiving an item.

--
The way you have done it, can be just as accurate, but much harder to setup.
You must manually calculate the percentage of every item.. and if you want to add or remove an item from the list, you'll have to reset the percentage of every item in the list.

for example.. let's remove
{itemId = 10559, minCount = 1, maxCount = 1, chance1 = 8000, chance2=7001},
This from the list, because we don't want that item to be in the list anymore.

Now there is a 1000 lottery 'gap', that if left alone would allow the player to lose.
But we want the player to always receive an item.. so we need to replace this item with another one..
Or re-adjust the rest of the items on the list.. to account for that missing 1000.

That's not easy.
It's long and tedious.. and that's with a round number of 1000.
(1000 / 8, and evenly distributing that amount to the 8 remaining items in the list.. would not maintain the correct chances of the items.)

What if we wanted to change something for 59 points?
There's no way to accurately distribute that 59 points in the list of the 8 remaining items. (59/8 = 7.375)
Some of the items will have to have a slightly elevated percentage, or a lower percentage.

--
For this particular goal, of giving a single item (or multiple items (you'd just run the lottery multiple times)) to the player..
I haven't found a more reliable or fast method to do so.

--
So in the lottery of items, in my version..

If the item has a chance of 1000..
It's minimum chance of being picked is 1/8 -> 12.5% chance (8 items in lottery)

It's maximum chance is 100% (because it's 1000/1000) if the other items in the lottery fail their own chance rolls.

It's over total chance in the entire lottery (summing up all the items) would be
1000/3800 = 0.263 -> 26.3% chance.

--
I'm not even sure what I'm trying to defend/describe at this point. lol
I just know it's the most accurate way I've found to do an item lottery, while also being extremely easy to setup. xD
 
Last edited:
The way you have done it, can be just as accurate, but much harder to setup.
You must manually calculate the percentage of every item.. and if you want to add or remove an item from the list, you'll have to reset the percentage of every item in the list.

for example.. let's remove
{itemId = 10559, minCount = 1, maxCount = 1, chance1 = 8000, chance2=7001},
This from the list, because we don't want that item to be in the list anymore.
Correct me if I am wrong, but players should always get a reward, no matter what..
(I have tested it)
I appreciate the feedback :)
 
Correct me if I am wrong, but players should always get a reward, no matter what..
(I have tested it)
I appreciate the feedback :)
I had assumed many things when looking at the script previously..
I believe your code is not functioning correctly, based on our previous conversation.

Here's some green text to look over.
Lua:
local config = {
    actionId = 45001,
    cooldown = {
       
        key = 8978, -- not used in the script.
       
    },
    rewards = {
        {itemId = 2148, minCount = 1, maxCount = 1, chance1 = 1000, chance2=1},
        {itemId = 2149, minCount = 1, maxCount = 1, chance1 = 5999, chance2=1001},
        {itemId = 2152, minCount = 1, maxCount = 1, chance1 = 7000, chance2=6000},
        {itemId = 10559, minCount = 1, maxCount = 1, chance1 = 8000, chance2=7001},
        {itemId = 10555, minCount = 1, maxCount = 1, chance1 = 9000, chance2=8001},
        {itemId = 10556, minCount = 1, maxCount = 1, chance1 = 9500, chance2=9001},
        {itemId = 10557, minCount = 1, maxCount = 1, chance1 = 9510, chance2=9501},
        {itemId = 10558, minCount = 1, maxCount = 1, chance1 = 10000, chance2=9511}
    }
}

local rewardChest = Action()

function rewardChest.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local rewardList = {} -- not used in the script.
    g = 0 -- global variable when it should be local.

    rand = math.random(10000) -- global variable when it should be local.
    for i = 1, #config.rewards do
        if rand >= config.rewards[i].chance1 or rand <= config.rewards[i].chance1 and rand >= config.rewards[i].chance2 then -- This is wrong. You are checking above and below and equal to for the first number. This will incorrectly give item chance.
            g = g + 1 -- Items further down on the list will have a higher chance of being obtained.
        end
    end
    if g == 0 then
        g = 1 -- this is a poor way to guarentee an item is given to the player if all the chances fail.
    end  

    if player:getItemCount(8978) > 0 then -- this check should be much earlier in the script.
        rand = g
        player:removeItem(8978,1)
        player:addItem(config.rewards[rand].itemId, math.random(config.rewards[rand].minCount, config.rewards[rand].maxCount), true)
        player:say("Received " .. ItemType(config.rewards[rand].itemId):getName():lower() .. " as reward.", TALKTYPE_MONSTER_SAY)
        doSendMagicEffect(player:getPosition(), CONST_ME_HOLYAREA)
    else
        player:say("You need a key!", TALKTYPE_MONSTER_SAY)
        return true -- incorrect placement
    end
end

rewardChest:aid(config.actionId)
rewardChest:register()

And, here's how I'd suggest to adjust it. (assuming you actually want this way.. instead of the way I commented before.)
Lua:
local config = {
    actionId = 45001,
    keyId = 8978,
    maxChance = 10000,
    rewards = {
    -- [{chance1, chance2}]
        [{   1,  1000}]  = {itemId = 2148,  minCount = 1, maxCount = 1},
        [{1001,  5999}]  = {itemId = 2149,  minCount = 1, maxCount = 1},
        [{6000,  7000}]  = {itemId = 2152,  minCount = 1, maxCount = 1},
        [{7001,  8000}]  = {itemId = 10559, minCount = 1, maxCount = 1},
        [{8001,  9000}]  = {itemId = 10555, minCount = 1, maxCount = 1},
        [{9001,  9500}]  = {itemId = 10556, minCount = 1, maxCount = 1},
        [{9501,  9510}]  = {itemId = 10557, minCount = 1, maxCount = 1},
        [{9511, 10000}]  = {itemId = 10558, minCount = 1, maxCount = 1}
    }
}

local rewardChest = Action()

function rewardChest.onUse(player, item, fromPosition, target, toPosition, isHotkey)

    if player:getItemCount(config.keyId) > 0 then
        player:say("You need a key!", TALKTYPE_MONSTER_SAY)
        return true
    end
    player:removeItem(config.keyId, 1)
   
    local rand = math.random(config.maxChance)
    while rand > 0 do
        for chance, reward in pairs(config.rewards) do
            if rand <= chance[2] and rand >= chance[1] then
                player:addItem(reward.itemId, math.random(reward.minCount, reward.maxCount), true)
                player:say("Received " .. ItemType(reward.itemId):getName():lower() .. " as reward.", TALKTYPE_MONSTER_SAY)
                doSendMagicEffect(player:getPosition(), CONST_ME_HOLYAREA)
                return true
            end
        end
        print("Error: Your table chances have gaps in the spread of numbers. Number gap found with [" .. rand .. "]")
    end
   
    return true
end

rewardChest:aid(config.actionId)
rewardChest:register()
 
Back
Top