• 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 0.X Quest random item in percent

zabuzo

Well-Known Member
Joined
Jun 10, 2016
Messages
238
Reaction score
54
How to create a quest with randoms rewards in this percents?

itemid | percent
Code:
2525 50%
4874 30%
2435 18%
2502 1%
2503 0.6%
2504 0.4%
 
Solution
How to create a quest with randoms rewards in this percents?

itemid | percent
Code:
2525 50%
4874 30%
2435 18%
2502 1%
2503 0.6%
2504 0.4%
Use storages for the quest portion of the script.

Use the code snippet below to give the player the items in your table, using the chances you've provided.
Lua:
local rewards = {
  --{itemid, chance} -- 100 = guaranteed, 0.001 = minimum chance
    {2525, 50},
    {4874, 30},
    {2435, 18},
    {2502, 1},
    {2503, 0.6},
    {2504, 0.4}
}

for i = 1, #rewards do
    if math.random(100000) <= rewards[i][2] * 1000 then
        doPlayerAddItem(cid, rewards[i][1], 1, true)
    end
end
How to create a quest with randoms rewards in this percents?

itemid | percent
Code:
2525 50%
4874 30%
2435 18%
2502 1%
2503 0.6%
2504 0.4%
Use storages for the quest portion of the script.

Use the code snippet below to give the player the items in your table, using the chances you've provided.
Lua:
local rewards = {
  --{itemid, chance} -- 100 = guaranteed, 0.001 = minimum chance
    {2525, 50},
    {4874, 30},
    {2435, 18},
    {2502, 1},
    {2503, 0.6},
    {2504, 0.4}
}

for i = 1, #rewards do
    if math.random(100000) <= rewards[i][2] * 1000 then
        doPlayerAddItem(cid, rewards[i][1], 1, true)
    end
end
 
Solution
Use storages for the quest portion of the script.

Use the code snippet below to give the player the items in your table, using the chances you've provided.
Lua:
local rewards = {
  --{itemid, chance} -- 100 = guaranteed, 0.001 = minimum chance
    {2525, 50},
    {4874, 30},
    {2435, 18},
    {2502, 1},
    {2503, 0.6},
    {2504, 0.4}
}

for i = 1, #rewards do
    if math.random(100000) <= rewards[i][2] * 1000 then
        doPlayerAddItem(cid, rewards[i][1], 1, true)
    end
end

Perfect! Thank you!
 
@Xikini
It's not 100%

Some times work, sometimes not, and shows this error on console:
Code:
[23:53:49.034] [Error - Action Interface] 
[23:53:49.034] data/actions/scripts/dungeon_chest.lua:onUse
[23:53:49.034] Description: 
[23:53:49.034] data/actions/scripts/dungeon_chest.lua:37: attempt to compare boolean with number
[23:53:49.034] stack traceback:
[23:53:49.034]     data/actions/scripts/dungeon_chest.lua:37: in function <data/actions/scripts/dungeon_chest.lua:1>

[23:53:53.544] [Error - Action Interface] 
[23:53:53.544] data/actions/scripts/dungeon_chest.lua:onUse
[23:53:53.544] Description: 
[23:53:53.544] data/actions/scripts/dungeon_chest.lua:37: attempt to compare boolean with number
[23:53:53.544] stack traceback:
[23:53:53.544]     data/actions/scripts/dungeon_chest.lua:37: in function <data/actions/scripts/dungeon_chest.lua:1>

[23:55:16.895] [Error - Action Interface] 
[23:55:16.895] data/actions/scripts/dungeon_chest.lua:onUse
[23:55:16.895] Description: 
[23:55:16.895] data/actions/scripts/dungeon_chest.lua:37: attempt to compare boolean with number
[23:55:16.895] stack traceback:
[23:55:16.896]     data/actions/scripts/dungeon_chest.lua:37: in function <data/actions/scripts/dungeon_chest.lua:1>

Code:
function onUse(cid, item, fromPosition, itemEx, toPosition)
    -- STORAGE
    local storage = 9603
    -- how to 5: check if player is in a dugeon (to avoid abuses)
    
    -- LEVEL
    local lvl = 8
    if getPlayerLevel(cid) < lvl then
     doPlayerSendCancel(cid, "Sorry, level: " .. lvl .. " or higher to complete this quest.")
     doSendMagicEffect(getCreaturePosition(cid), CONST_ME_POFF)
     return true
    end
    -- ITEMS random percent
    local rewardid
    local rewards = {
      --{itemid, chance} -- 100 = guaranteed, 0.001 = minimum chance
        {2525, 50},
        {4874, 30},
        {2435, 18},
        {2502, 1},
        {2503, 0.6},
        {2504, 0.4}
    }
    for i = 1, #rewards do
        if math.random(100000) <= rewards[i][2] * 1000 then
            rewardid = rewards[i][1]
        end
    end
    -- TEMPO
    local mins = 60
    local hours = 60 * 60
    local days = 24 * 60 * 60
    local time = 1 * mins
    -- FUNC
    local timeNow = os.time()
    if timeNow - getPlayerStorageValue(cid, storage) >= 0 then
     if getPlayerFreeCap(cid) >= getItemWeightById(rewardid, 1) then
        doPlayerAddItem(cid, rewardid, 1)
        doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'You have found a '..getItemNameById(rewardid)..'.')
        setPlayerStorageValue(cid, storage, timeNow + time)
        -- teleport to exit
        local exit_pos = {x= 956, y=1048, z=6}
        doTeleportThing(cid, exit_pos)
        doSendMagicEffect(getPlayerPosition(cid), 10)
     else
        doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'You have found a '..getItemNameById(rewardid)..'. It weighs '..getItemWeightById(rewardid, 1)..'.00 and it is too heavy.')          
     end
    elseif getPlayerStorageValue(cid, storage) < 0 then
     doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'It is empty.')
    elseif getPlayerStorageValue(cid, storage)-timeNow > days then
     doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'It is empty, you must wait '.. math.ceil(((getPlayerStorageValue(cid, storage)) - timeNow)/days) ..' days to do it again.')
    elseif getPlayerStorageValue(cid, storage)-timeNow > hours then
     doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'It is empty, you must wait '.. math.ceil(((getPlayerStorageValue(cid, storage)) - timeNow)/hours) ..' hours to do it again.')
    else
     doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'It is empty, you must wait '.. math.ceil(((getPlayerStorageValue(cid, storage)) - timeNow)/mins) ..' minutes to do it again.')
    end
    return true
end

Did u know why?
 
There is the possibility that no item on the list is obtained, and therefore the error, you should check first if an item could be obtained.
per example:
Code:
if rewardid then return true end
 
There is the possibility that no item on the list is obtained, and therefore the error, you should check first if an item could be obtained.
per example:
Code:
if rewardid then return true end

Where is this possibility so i can fix?
Players always have to get an item:
Code:
        {2525, 50},
        {4874, 30},
        {2435, 18},
        {2502, 1},
        {2503, 0.6},
        {2504, 0.4}
50+30=80+18=98+1=99+0.6+0.4=100
 
Where is this possibility so i can fix?
Players always have to get an item:
Code:
        {2525, 50},
        {4874, 30},
        {2435, 18},
        {2502, 1},
        {2503, 0.6},
        {2504, 0.4}
50+30=80+18=98+1=99+0.6+0.4=100
Are they supposed to get only one item from the list?
Just gotta change how percentages are calculated in the loop a bit then.
Lua:
local rewards = {
    {2525, {501, 1000}}, -- 1000 - 501 = 499+1 / 10 = 50% (you add 1 to the total, because we are including the base number in the calculation.)
    {4874, {201, 500}}, -- 500 - 201 = 299+1 / 10 = 30%
    {2435, {21, 200}}, -- 200 - 21 = 179+1 / 10 = 18%
    {2502, {11, 20}}, -- 20 - 11 = 9+1 / 10 = 1%
    {2503, {5, 10}}, -- 10 - 5 = 5+1 / 10 = 0.6%
    {2504, {1, 4}} -- 4 - 1 = 3+1 / 10 = 0.4% (which is easier to see when you look at the smallest values)
}

local rand = math.random(1000)
for i = 1, #rewards do
    if rand >= rewards[i][2][1] and rand <= rewards[i][2][2] then
        rewardid = rewards[i][1]
        break
    end
end
 
You can be smart and do what xikini said above, or you can be lazy and just put variable 'rewardid' to 2525 by default (the player will be guaranteed to get the item with 50% chance if everything else fails).
 
Where is this possibility so i can fix?
Players always have to get an item:
Code:
        {2525, 50},
        {4874, 30},
        {2435, 18},
        {2502, 1},
        {2503, 0.6},
        {2504, 0.4}
50+30=80+18=98+1=99+0.6+0.4=100
The possibilities do not add up in that way is something more complicated than adding, but if you want the code to find if or if any item on the list can simply use this:
Code:
repeat
    if math.random(100000) <= rewards[i][2] * 1000 then
        rewardid = rewards[i][1]
    end
until rewardid
in this way you will not have to add articles for defects, it will only be lucky.

Any programmer sees this and would be afraid to stumble upon a loop to infinity, but for this loop to be infinite a list with very remote probabilities and few items on the list would be necessary, which is not the case, so it will work.
 
Back
Top