• 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 [Boss Rewards] How to exequte raid after boss dies and set cooldown to portals and rewards?

ralke

(҂ ͠❛ ෴ ͡❛)ᕤ
Joined
Dec 17, 2011
Messages
1,470
Solutions
27
Reaction score
844
Location
Santiago - Chile
GitHub
ralke23
Twitch
ralke23
Using OTX 2 (tfs 0.3.7)

Hi! I've been trying a new method to do raids and rewards from bosses. At the moment, is intended to work but is messy, the reason I open this thread, is to someone help me finishing this as a request, if possible :D

The first part was to create a teleport with action id after Ghazbaran dies. This works well, added
Code:
corpse="5024" corpseAid="8421"/>
to the Ghazabaran.xml. The next thing was to script the teleport, I gave it a cooldown to stepIn the teleport after you stepIn once, a chance to enter to reward room, a chance to teleport you out and start the stepIn cooldown

Code:
local duration = 30
local per = 10
local outfit = 11  -- looktype
local chance = 30    -- in %
local newPos = {x = 1177, y = 1094, z = 15}
local failPos = {x = 1156, y = 1090, z = 14}
local cooldownStorage = 39001


function onStepIn(cid, item, position, lastPosition, fromPosition, toPosition, actor)
    -- cooldown
    local cur_time = os.time()
    local cooldown = getPlayerStorageValue(cid, cooldownStorage)
    if cooldown > cur_time then
        doSendMagicEffect(fromPosition, CONST_ME_POFF)
        doPlayerSendCancel(cid, "[Boss Room] You can try to enter again in  " .. os.date('!%H:%M:%S minutes.', (cooldown - cur_time)))
        doSendMagicEffect(newPos, CONST_ME_WATERSPLASH)
        return true
    end
    setPlayerStorageValue(cid, cooldownStorage, cur_time + 5)
    
    if(not isPlayer(cid)) then
        return true
    end
    local outfitt = getCreatureOutfit(cid)
        outfitt.lookType = outfit
    if(math.random(1, 100) <= chance) then
        doSetCreatureOutfit(cid, outfitt, duration*1000)
        doTeleportThing(cid, newPos)
        doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You absorbed the spirit of Ghazbaran.")
        doSendMagicEffect(newPos, CONST_ME_WATERSPLASH)
    else
        doPlayerSendCancel(cid, "[Boss Room] Good luck next time!")
        doTeleportThing(cid,fromPosition)
        doSendMagicEffect(fromPosition,2)
        doCreatureAddHealth(cid, -(getCreatureMaxHealth(cid) * per / 100))
        doTeleportThing(cid, failPos)
        doSendMagicEffect(failPos, CONST_ME_CRAPS)
        setPlayerStorageValue(cid, cooldownStorage, cur_time + 900)
    end

    return true
end

This two works well. I also added a decayTo function to the teleport id 8421 at items.xml to make it.


The problem starts here, I tried with this creaturescript to exequte a raid after the monster dies (in this case, Ghazbaran) with the intention of replacing the monster after its death. But the important thing of this is that the monster has to spawn at the same time that the cooldownStorage of the teleport expires.
Code:
     setPlayerStorageValue(cid, cooldownStorage, cur_time + 900)

The creaturescript:
I got this error when using it
onkillghaz.png
Code:
local raidName = "Ghazbaran"
function onKill(cid, target, lastHit)
    if lastHit and getCreatureName(target):lower() == 'ghazbaran' then
        doCreatureSay(cid, "A PORTAL TO GHAZBARAN'S REWARD ROOM HAS BEEN OPENED!", TALKTYPE_ORANGE_1)
        doCreatureSay(cid, "A PORTAL TO GHAZBARAN'S REWARD ROOM HAS BEEN OPENED!", TALKTYPE_ORANGE_1)
        doCreatureSay(cid, "A PORTAL TO GHAZBARAN'S REWARD ROOM HAS BEEN OPENED!", TALKTYPE_ORANGE_1)
        doCreatureSay(cid, "Next".. raidName .." raid in 60 minutes!", TALKTYPE_ORANGE_1)
        Game.startRaid(raidName)
    end
    return true
end

The propose of this is that the player will have:


  • A % of chance to access to the reward room after killing Ghazbaran. He can get in, or be rejected.
  • If player got rejected its going to have to wait till' Ghazbaran appear again.
  • Players will be motivated to bring multiple caracteres to get more loot

The third part would be the raid file, but I think this is not the way to script this...
Anyways, here it is:

Code:
<?xml version="1.0" encoding="utf-8"?>
<raid>
    <!-- 
    // Raid System by 5mok3
    // DO NOT CHANGE INTERVAL UNLESS YOU ARE SURE WHAT YOU ARE DOING!!
    -->

  <!--Announcements-->
  <announce delay="1000" type="Event" message="An ancient evil is awakening in the mines beneath Hrodmir." />
  <announce delay="30000" type="Event" message="Demonic entities are entering the mortal realm in the Hrodmir mines." />
  <announce delay="60000" type="Event" message="The demonic master has revealed itself in the mines of Hrodmir." />
  <!--Single Spawns-->
  <singlespawn delay="60000" name="Ghazbaran" x="32228" y="31163" z="15" />
  <!--Area Spawns-->
  <areaspawn delay="53000" fromx="32194" fromy="30986" fromz="14" tox="32213" toy="31012" toz="14">
    <monster name="Deathslicer" amount="12" />
  </areaspawn>
  <areaspawn delay="55000" fromx="32194" fromy="30986" fromz="14" tox="32213" toy="31012" toz="14">
    <monster name="Juggernaut" amount="5" />
  </areaspawn>
  <areaspawn delay="56000" fromx="32194" fromy="30986" fromz="14" tox="32213" toy="31012" toz="14">
    <monster name="Fury" amount="8" />
  </areaspawn>
  <areaspawn delay="58000" fromx="32194" fromy="30986" fromz="14" tox="32213" toy="31012" toz="14">
    <monster name="Demon" amount="6" />
  </areaspawn>
</raid>

The last step has to be a daily reward chest. I've seen lots of this scripts on OtLand but haven't tested yet. The main thing I need on this chest is to fit, somehow, the time of cooldownStorage of the teleport and the time of the Raid exeqution.

At the moment I could kick out players from reward room after picking their reward with doTeleportThing after use the chest, but they should also have a time limit to stay in the boss room, in case the guy kill Ghazbaran again and he's not able to pick `daily' reward because of the chest cooldown. The key is to fit this time limit with the raids and the teleport CDs.

The chest will have the same loot that Ghazbaran, in chances, based on this examples, and as I say, it should have the same time cooldown that the raids / portals, or
one close, to fit it with all the system.


Thanks for reading, hope you guys can help me again
Regards, ralke!
 
Last edited:
I asumme you are using tfs 0.3.6, what you can do is to try addEvent instead of raid:

Lua:
local delay = 60 * 60 * 1000
local monsterName = "Ghazbaran"
local position = getThingPosition(target)

addEvent(doCreateMonster, delay, monsterName, position)
 
Oh yeah that may be because the Ghazbaran is already dead?
You can use a fixed position then:

Lua:
local position = {x = 1000, y = 1000, z = 7}
 
Good! Solution was simple :D
This is how it looks now
Code:
local duration = 30
local per = 10
local outfit = 11  -- looktype
local chance = 30    -- in %
local newPos = {x = 1177, y = 1094, z = 15}
local failPos = {x = 1156, y = 1090, z = 14}
local cooldownStorage = 39001


function onStepIn(cid, item, position, lastPosition, fromPosition, toPosition, actor)
    -- cooldown
    local cur_time = os.time()
    local cooldown = getPlayerStorageValue(cid, cooldownStorage)
    if cooldown > cur_time then
        doSendMagicEffect(fromPosition, CONST_ME_POFF)
        doPlayerSendCancel(cid, "[Boss Room] You can try to enter again in " .. os.date('!%H:%M:%S minutes.', (cooldown - cur_time)))
        doTeleportThing(cid, failPos)
        doSendMagicEffect(fromPosition, CONST_ME_WATERSPLASH)
        return true
    end
    setPlayerStorageValue(cid, cooldownStorage, cur_time + 5)
 
    if(not isPlayer(cid)) then
        return true
    end
    local outfitt = getCreatureOutfit(cid)
        outfitt.lookType = outfit
    if(math.random(1, 100) <= chance) then
        doSetCreatureOutfit(cid, outfitt, duration*1000)
        doTeleportThing(cid, newPos)
        doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You absorbed the spirit of Ghazbaran.")
        doSendMagicEffect(newPos, CONST_ME_WATERSPLASH)
        setPlayerStorageValue(cid, cooldownStorage, cur_time + 900)
    else
        doPlayerSendCancel(cid, "[Boss Room] Good luck next time!")
        doTeleportThing(cid,fromPosition)
        doSendMagicEffect(fromPosition,2)
        doCreatureAddHealth(cid, -(getCreatureMaxHealth(cid) * per / 100))
        doTeleportThing(cid, failPos)
        doSendMagicEffect(failPos, CONST_ME_CRAPS)
        setPlayerStorageValue(cid, cooldownStorage, cur_time + 900)
    end

    return true
end

And creaturescript:
Code:
local delay = 1 * 60 * 1000
local monsterName = "Ghazbaran"
local position = {x = 1175, y = 1091, z = 15}
local raidName = "Ghazbaran"
function onKill(cid, target, lastHit)
    if lastHit and getCreatureName(target):lower() == 'ghazbaran' then
        doCreatureSay(cid, "A PORTAL TO GHAZBARAN'S REWARD ROOM HAS BEEN OPENED!", TALKTYPE_ORANGE_1)
        doCreatureSay(cid, "A PORTAL TO GHAZBARAN'S REWARD ROOM HAS BEEN OPENED!", TALKTYPE_ORANGE_1)
        doCreatureSay(cid, "A PORTAL TO GHAZBARAN'S REWARD ROOM HAS BEEN OPENED!", TALKTYPE_ORANGE_1)
        doCreatureSay(cid, "Demonic entities are entering the mortal realm. ".. raidName .." will spawn again in 60 minutes. An ancient evil is awakening!", TALKTYPE_ORANGE_1)
        addEvent(doCreateMonster, delay, monsterName, position)
    end
    return true
end

Going to start scripting the chest now, I'll reply if I got more troubles, thanks a lot @Azakelis
Post automatically merged:

@Azakelis now im troubling with this... I added the
Code:
local failPos = {x = 1156, y = 1090, z = 14}
and
Code:
                 doTeleportThing(cid, failPos)
to the script of Limos chest. It seems that does not make any trouble, the problem is here (line 68), what i'm missing?
chest_error.png
the action script...
Code:
-- Time Chest by Limos
local failPos = {x = 1156, y = 1090, z = 14}
local config = {
     exhausttime = 7200, -- time in seconds
     exhauststorage = 43807,
     level = 50 -- minimum level to open the chest
}

function onUse(cid, item, fromPosition, itemEx, toPosition)
     local rewarditems = {
         [50] = {
             nextlevel = 50,
             {id = 3982, chance = 5, count = 1}, -- start with the lowest chances
             {id = 2476, chance = 10, count = 1},
             {id = 2479, chance = 15, count = 1},
             {id = 2148, chance = 70, count = math.random(1, 50)}
         },
         [100] = {
             nextlevel = 100,
             {id = 7730, chance = 5, count = 1},
             {id = 2466, chance = 10, count = 1},
             {id = 2497, chance = 15, count = 1},
             {id = 2152, chance = 70, count = math.random(1, 20)}
         },
         [150] = {
             nextlevel = 200,
             {id = 2492, chance = 5, count = 1},
             {id = 2498, chance = 10, count = 1},
             {id = 2195, chance = 15, count = 1},
             {id = 2152, chance = 70, count = math.random(20, 50)}
         },
         [200] = {
             nextlevel = 10000,
             {id = 2472, chance = 5, count = 1},
             {id = 2470, chance = 10, count = 1},
             {id = 2157, chance = 15, count = 1},
             {id = 2160, chance = 70, count = math.random(1, 5)}
         }
     }
     if getPlayerLevel(cid) < config.level then
         doSendMagicEffect(getThingPos(cid), CONST_ME_POFF)
         doPlayerSendCancel(cid, "You need to be level "..config.level.." to open the chest.")
         return true
     end

     if exhaustion.check(cid, config.exhauststorage) then
         local time = exhaustion.get(cid, config.exhauststorage)
         local hours, minutes, seconds = math.floor (time / 3600), math.floor ((time - ((math.floor (time / 3600)) * 3600))/ 60), time - ((math.floor (time/60)) * 60)
         if time >= 3600 then
             text = hours.." "..(hours == 1 and "hour" or "hours")..", "..minutes.." "..(minutes == 1 and "minute" or "minutes").." and "..seconds.." "..(seconds == 1 and "second" or "seconds")
         elseif time >= 120 then
             text = minutes.." "..(minutes == 1 and "minute" or "minutes").." and "..seconds.." "..(seconds == 1 and "second" or "seconds")
         else
             text = seconds.." "..(seconds == 1 and "second" or "seconds")
         end
         doSendMagicEffect(getThingPos(cid), CONST_ME_POFF)
         doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "It is empty. You need to wait "..text.." before you can get a reward again.")
         return true
     end

     local chance = math.random(1,100)
     for v, x in pairs(rewarditems) do
         if getPlayerLevel(cid) >= v and getPlayerLevel(cid) < x.nextlevel then
             level = v
         end
     end

     for i = 1, #rewarditems[level], 1 do
         if chance < rewarditems[level][i].chance then
             local info = getItemInfo(rewarditems[level][i].id)
             if rewarditems[level][i].count > 1 then
                 text = rewarditems[level][i].count .. " " .. info.plural
             else
                 text = info.article .. " " .. info.name
             end

             local item = doCreateItemEx(rewarditems[level][i].id, rewarditems[level][i].count)
             if doPlayerAddItemEx(cid, item, false) ~= RETURNVALUE_NOERROR then
                 doSendMagicEffect(getThingPos(cid), CONST_ME_POFF)
                 text = "You have found a reward. It is to heavy or you have not enough space."
             else
                 text = "You have found " .. text .. "."
                 exhaustion.set(cid, config.exhauststorage, config.exhausttime)
                 doTeleportThing(cid, failPos)
             end
             doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, text)
             return true
         else
             chance = chance - rewarditems[level][i].chance
         end
     end
end

Also wanted to ask, how can I use this kind of cooldown in the chest that seems more simplyfied?
Code:
    -- cooldown
    local cur_time = os.time()
    local cooldown = getPlayerStorageValue(cid, cooldownStorage)
    if cooldown > cur_time then
        doSendMagicEffect(failPos, CONST_ME_POFF)
        doPlayerSendCancel(cid, "[Boss Room] You can try to enter again in " .. os.date('!%H:%M:%S minutes.', (cooldown - cur_time)))
        doTeleportThing(cid, failPos)
        doSendMagicEffect(failPos, CONST_ME_CRAPS)
        return true
    end
    setPlayerStorageValue(cid, cooldownStorage, cur_time + 5)
 
Last edited:
I would try to change te rewards to something like this:
Lua:
         [200] = {
             nextlevel = 10000,
             rewards = {
                {id = 2472, chance = 5, count = 1},
                {id = 2470, chance = 10, count = 1},
                {id = 2157, chance = 15, count = 1},
                {id = 2160, chance = 70, count = math.random(1, 5)}
                }
            }

and access it like this:
Lua:
for i = 1, #rewarditems[level].rewards, 1 do

I dont quite get your second question.
 
@Azakelis The chest started to work and I'm getting the reward, but the cooldowns are not working, there's no exhaust you can use the chest any time. There's no errors in console.

On the second question I refer to make the cooldown of the chest in a similar way that the teleport scripted before, anyways, if the cooldown starts working it can be scripted in other way :). Here is the script:
Code:
-- Time Chest by Limos
local failPos = {x = 1156, y = 1090, z = 14}
local config = {
     exhausttime = 7200, -- time in seconds
     exhauststorage = 43807,
     level = 50 -- minimum level to open the chest
}

function onUse(cid, item, fromPosition, itemEx, toPosition)
     local rewarditems = {
         [50] = {
             nextlevel = 100,
             rewards = {
                {id = 2472, chance = 5, count = 1},
                {id = 2470, chance = 10, count = 1},
                {id = 2157, chance = 15, count = 1},
                {id = 2160, chance = 70, count = math.random(1, 5)}
                }},
         [100] = {
             nextlevel = 150,
             rewards = {
                {id = 2472, chance = 5, count = 1},
                {id = 2470, chance = 10, count = 1},
                {id = 2157, chance = 15, count = 1},
                {id = 2160, chance = 70, count = math.random(1, 5)}
                }},
         [150] = {
             nextlevel = 200,
             rewards = {
                {id = 2472, chance = 5, count = 1},
                {id = 2470, chance = 10, count = 1},
                {id = 2157, chance = 15, count = 1},
                {id = 2160, chance = 70, count = math.random(1, 5)}
                }},
         [200] = {
             nextlevel = 10000,
             rewards = {
                {id = 2472, chance = 5, count = 1},
                {id = 2470, chance = 10, count = 1},
                {id = 2157, chance = 15, count = 1},
                {id = 2160, chance = 70, count = math.random(1, 5)}
                }}
            }
     if getPlayerLevel(cid) < config.level then
         doSendMagicEffect(getThingPos(cid), CONST_ME_POFF)
         doPlayerSendCancel(cid, "You need to be level "..config.level.." to open the chest.")
         return true
     end

     if exhaustion.check(cid, config.exhauststorage) then
         local time = exhaustion.get(cid, config.exhauststorage)
         local hours, minutes, seconds = math.floor (time / 3600), math.floor ((time - ((math.floor (time / 3600)) * 3600))/ 60), time - ((math.floor (time/60)) * 60)
         if time >= 3600 then
             text = hours.." "..(hours == 1 and "hour" or "hours")..", "..minutes.." "..(minutes == 1 and "minute" or "minutes").." and "..seconds.." "..(seconds == 1 and "second" or "seconds")
         elseif time >= 120 then
             text = minutes.." "..(minutes == 1 and "minute" or "minutes").." and "..seconds.." "..(seconds == 1 and "second" or "seconds")
         else
             text = seconds.." "..(seconds == 1 and "second" or "seconds")
         end
         doSendMagicEffect(getThingPos(cid), CONST_ME_POFF)
         doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "It is empty. You need to wait "..text.." before you can get a reward again.")
         return true
     end

     local chance = math.random(1,100)
     for v, x in pairs(rewarditems) do
         if getPlayerLevel(cid) >= v and getPlayerLevel(cid) < x.nextlevel then
             level = v
         end
     end

     for i = 1, #rewarditems[level].rewards, 1 do
         if chance < rewarditems[level].rewards[i].chance then
             local info = getItemInfo(rewarditems[level].rewards[i].id)
             if rewarditems[level].rewards[i].count > 1 then
                 text = rewarditems[level].rewards[i].count .. " " .. info.plural
             else
                 text = info.article .. " " .. info.name
             end

             local item = doCreateItemEx(rewarditems[level].rewards[i].id, rewarditems[level].rewards[i].count)
             if doPlayerAddItemEx(cid, item, false) ~= RETURNVALUE_NOERROR then
                 doSendMagicEffect(getThingPos(cid), CONST_ME_POFF)
                 text = "You have found a reward. It is to heavy or you have not enough space."
             else
                 text = "You have found " .. text .. "."
                 exhaustion.set(cid, config.exhauststorage, config.exhausttime)
                 doTeleportThing(cid, failPos)
             end
             doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, text)
             return true
         else
             chance = chance - rewarditems[level].rewards[i].chance
         end
     end
end
Post automatically merged:

Edit

Thread solved!
Solution

Code:
-- Time Chest by Limos
local failPos = {x = 1156, y = 1090, z = 14}
local cooldownStorage = 47632
local config = {
     level = 50 -- minimum level to open the chest
}

function onUse(cid, item, fromPosition, itemEx, toPosition)
     local rewarditems = {
         [50] = {
             nextlevel = 100,
             rewards = {
                {id = 2472, chance = 5, count = 1},
                {id = 2470, chance = 10, count = 1},
                {id = 2157, chance = 15, count = 1},
                {id = 2160, chance = 70, count = math.random(1, 5)}
                }},
         [100] = {
             nextlevel = 150,
             rewards = {
                {id = 2472, chance = 5, count = 1},
                {id = 2470, chance = 10, count = 1},
                {id = 2157, chance = 15, count = 1},
                {id = 2160, chance = 70, count = math.random(1, 5)}
                }},
         [150] = {
             nextlevel = 200,
             rewards = {
                {id = 2472, chance = 5, count = 1},
                {id = 2470, chance = 10, count = 1},
                {id = 2157, chance = 15, count = 1},
                {id = 2160, chance = 70, count = math.random(1, 5)}
                }},
         [200] = {
             nextlevel = 10000,
             rewards = {
                {id = 2472, chance = 5, count = 1},
                {id = 2470, chance = 10, count = 1},
                {id = 2157, chance = 15, count = 1},
                {id = 2160, chance = 70, count = math.random(1, 5)}
                }}
            }
     if getPlayerLevel(cid) < config.level then
         doSendMagicEffect(getThingPos(cid), CONST_ME_POFF)
         doPlayerSendCancel(cid, "You need to be level "..config.level.." to open the chest.")
         return true
     end

    -- cooldown
    local cur_time = os.time()
    local cooldown = getPlayerStorageValue(cid, cooldownStorage)
    if cooldown > cur_time then
        doSendMagicEffect(failPos, CONST_ME_POFF)
        doPlayerSendCancel(cid, "[Boss Room] You can try open the chest again in " .. os.date('!%H:%M:%S minutes.', (cooldown - cur_time)))
        doTeleportThing(cid, failPos)
        doSendMagicEffect(failPos, CONST_ME_CRAPS)
        return true
    end
    setPlayerStorageValue(cid, cooldownStorage, cur_time + 5)

     local chance = math.random(1,100)
     for v, x in pairs(rewarditems) do
         if getPlayerLevel(cid) >= v and getPlayerLevel(cid) < x.nextlevel then
             level = v
         end
     end

     for i = 1, #rewarditems[level].rewards, 1 do
         if chance < rewarditems[level].rewards[i].chance then
             local info = getItemInfo(rewarditems[level].rewards[i].id)
             if rewarditems[level].rewards[i].count > 1 then
                 text = rewarditems[level].rewards[i].count .. " " .. info.plural
             else
                 text = info.article .. " " .. info.name
             end

             local item = doCreateItemEx(rewarditems[level].rewards[i].id, rewarditems[level].rewards[i].count)
             if doPlayerAddItemEx(cid, item, false) ~= RETURNVALUE_NOERROR then
                 doSendMagicEffect(getThingPos(cid), CONST_ME_POFF)
                 text = "You have found a reward. It is to heavy or you have not enough space."
             else
                 text = "You have found " .. text .. "."
    setPlayerStorageValue(cid, cooldownStorage, cur_time + 900)
                 doTeleportThing(cid, failPos)
             end
             doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, text)
             return true
         else
             chance = chance - rewarditems[level].rewards[i].chance
         end
     end
end

If someone is going to use, put the same storage on the local cooldownStorage of the chest and the teleport
Regards!
Post automatically merged:

Can I ask a last thing? I'm trying to increase the number of items on the rewards, for example, receive a sword, a mace, a gem, and gold, instead of only receiving a sword. The goal is to make the chest give the Ghazbaran loot in chances. Tried with
Code:
         [100] = {
             nextlevel = 150,
             rewards = {
                {id = {2472, 2470}, chance = 5, count = 1},
                {id = {2472, 2470}, chance = 10, count = 1},
                {id = {2472, 2470}, chance = 15, count = 1},
                {id = {2472, 2470}, chance = 70, count = math.random(1, 5)}
                }},
and throws this error
item chance.png
 
Last edited:
When the getItemInfo() cannot find item by id it returns false:
1611207647119.png

That means the provided id by getItemInfo(rewarditems[level].rewards.id) is wrong somehow, try printing it out.
 
@Azakelis I tried to set some prints but there's no result. I also tried today with the chest and there's other error, maybe it's related to the new cooldown function I placed in the script. Now is giving error on line :72 and :74. You can use the chest, it does not give you rewards but "sometimes" it kicks you out to the failPos. Everything started to get messy :/

Code:
-- Time Chest by Limos
local failPos = {x = 1156, y = 1090, z = 14}
local cooldownStorage = 39001
local config = {
     level = 50 -- minimum level to open the chest
}

function onUse(cid, item, fromPosition, itemEx, toPosition)
     local rewarditems = {
         [50] = {
             nextlevel = 100,
             rewards = {
                {id = {2472, 2470}, chance = 5, count = 1},
                {id = 2470, chance = 10, count = 1},
                {id = 2157, chance = 15, count = 1},
                {id = 2160, chance = 70, count = math.random(1, 5)}
                }},
         [100] = {
             nextlevel = 150,
             rewards = {
                {id = {2472, 2470}, chance = 5, count = 1},
                {id = {2472, 2470}, chance = 10, count = 1},
                {id = {2472, 2470}, chance = 15, count = 1},
                {id = {2472, 2470}, chance = 70, count = math.random(1, 5)}
                }},
         [150] = {
             nextlevel = 200,
             rewards = {
                {id = 2472, chance = 5, count = 1},
                {id = 2470, chance = 10, count = 1},
                {id = 2157, chance = 15, count = 1},
                {id = 2160, chance = 70, count = math.random(1, 5)}
                }},
         [200] = {
             nextlevel = 10000,
             rewards = {
                {id = 2472, chance = 5, count = 1},
                {id = 2470, chance = 10, count = 1},
                {id = 2157, chance = 15, count = 1},
                {id = 2160, chance = 70, count = math.random(1, 5)}
                }}
            }
     if getPlayerLevel(cid) < config.level then
         doSendMagicEffect(getThingPos(cid), CONST_ME_POFF)
         doPlayerSendCancel(cid, "You need to be level "..config.level.." to open the chest.")
         return true
     end

    -- cooldown
    local cur_time = os.time()
    local cooldown = getPlayerStorageValue(cid, cooldownStorage)
    if cooldown > cur_time then
        doSendMagicEffect(failPos, CONST_ME_POFF)
        doPlayerSendCancel(cid, "[Boss Room] You can try open the chest again in " .. os.date('!%H:%M:%S minutes.', (cooldown - cur_time)))
        doTeleportThing(cid, failPos)
        doSendMagicEffect(failPos, CONST_ME_CRAPS)
        return true
    end
    setPlayerStorageValue(cid, cooldownStorage, cur_time + 5)

     local chance = math.random(1,100)
     for v, x in pairs(rewarditems) do
         if getPlayerLevel(cid) >= v and getPlayerLevel(cid) < x.nextlevel then
             level = v
         end
     end

     for i = 1, #rewarditems[level].rewards, 1 do
         if chance < rewarditems[level].rewards[i].chance then
             local info = getItemInfo(rewarditems[level].rewards[i].id)
             if rewarditems[level].rewards[i].count > 1 then
                 text = rewarditems[level].rewards[i].count .. " " .. info.plural
             else
                 text = info.article .. " " .. info.name 
             end

             local item = doCreateItemEx(rewarditems[level].rewards[i].id, rewarditems[level].rewards[i].count)
             if doPlayerAddItemEx(cid, item, false) ~= RETURNVALUE_NOERROR then
                 doSendMagicEffect(getThingPos(cid), CONST_ME_POFF)
                 text = "You have found a reward. It is to heavy or you have not enough space."
             else
                 text = "You have found " .. text .. "."
    setPlayerStorageValue(cid, cooldownStorage, cur_time + 900)
                 doTeleportThing(cid, failPos)
             end
             doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, text)
             return true
         else
             chance = chance - rewarditems[level].rewards[i].chance
         end
     end
end

info boolean.png
 
The way you are wanting to do this would require you to change a fair amount of the reward script.

I'd suggest adding all of the items the player is going to get into a temporary table, and then using this function to actually give the player the items.

--
For learnings sake, you're getting that error because it gets to this part of the table, and expects a value, but is instead getting a table.
At that point getItemInfo returns false, which is a boolean value.
Lua:
local rewarditems = {
         [50] = {
             nextlevel = 100,
             rewards = {
                {id =
 
Hi @Xikini !! Thanks for replying my thread, your help is very appreciated as always!
I've installed the giveItemsFromTable function
Code:
function giveItemsFromTable(cid, table_location)
   local item_count_in_table = #table_location
   local reward_count = 0
   local tmp = 0
   local weight = 8
   local c_ = {}
   local v = 2
   c_[v - 1] = 1987
   if item_count_in_table > 8 then
       c_[v - 1] = 1988
       weight = 18
   end
   c_[v] = doCreateItemEx(c_[1], 1)
   if item_count_in_table > 20 then
       repeat
           tmp = 1987
           v = v + 1
           if item_count_in_table > 20 * (v - 2) + 8 - (v - 2) then
               tmp = 1988
               weight = weight + 10
           end
           weight = weight + 8
           c_[v] = doAddContainerItem(c_[v - 1], tmp, 1)
           if tmp == 1988 and item_count_in_table < 20 * (v - 1) - (v - 3) or tmp == 1987 then
               v = 0
           end
       until v == 0
   end
   v = 2
   for n = 1, #c_ do
       tmp = 20
       if c_[v + 1] then
           tmp = 19
       end
       for m = 1, tmp do
           reward_count = reward_count + 1
           tmp = table_location[reward_count]
           if tmp then
               doAddContainerItem(c_[v], tmp[1], tmp[2])
               weight = weight + getItemWeightById(tmp[1], tmp[2])
           else
               break
           end
       end
       v = v + 1
   end

   if doPlayerAddItemEx(cid, c_[2], false) == RETURNVALUE_NOERROR then
       doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You have found a " .. getItemNameById(c_[1]) .. " weighing ".. string.format("%.2f", weight) .." oz.")
       return true
   else
       local cap = getPlayerFreeCap(cid)
       if cap < weight then
           doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Require " .. string.format("%.2f", weight - cap) .. " more capacity to receive this reward weighing ".. string.format("%.2f", weight) .." oz.")
       else
           doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You require more inventory space to receive this reward.")
       end
   end
   return false
end

I know this should be the guide to change my script
Code:
local function giveReward(cid, table_location)
   local milliseconds = os.mtime()
   local item_count_in_table = #table_location
.
.
doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You have found a " .. getItemNameById(c_[1]) .. " weighing ".. string.format("%.2f", weight) .." oz.\nUnique items in table: " .. item_count_in_table .. ". Function took " .. (os.mtime() - milliseconds)/1000 .. " seconds to complete.")

But it will take me too long to figure out how to merge it with my script. It is possible that you can give me a sample that works? Merging it with my script, or doing from scratch if you consider that it needs to. For example:
  • Receive reward from the chest, with the time cooldown, and teleport player out after picking the reward
  • The reward can be (A) a bag with a sword, a mace, an axe, a bow, etc. and (B) a bag with 10-100 gold coins (math random), 2 talons, 4 ham
  • Give a chance to obtain bag (A) or bag (B) and test if chances, math.randoms, containers, etc. start working
If you can do, this will help me to know how to correctly place the loots, chances, item ammounts, and math randoms.

Thanks for helping me again,
ralke
 
Hi @Xikini !! Thanks for replying my thread, your help is very appreciated as always!
I've installed the giveItemsFromTable function
Code:
function giveItemsFromTable(cid, table_location)
   local item_count_in_table = #table_location
   local reward_count = 0
   local tmp = 0
   local weight = 8
   local c_ = {}
   local v = 2
   c_[v - 1] = 1987
   if item_count_in_table > 8 then
       c_[v - 1] = 1988
       weight = 18
   end
   c_[v] = doCreateItemEx(c_[1], 1)
   if item_count_in_table > 20 then
       repeat
           tmp = 1987
           v = v + 1
           if item_count_in_table > 20 * (v - 2) + 8 - (v - 2) then
               tmp = 1988
               weight = weight + 10
           end
           weight = weight + 8
           c_[v] = doAddContainerItem(c_[v - 1], tmp, 1)
           if tmp == 1988 and item_count_in_table < 20 * (v - 1) - (v - 3) or tmp == 1987 then
               v = 0
           end
       until v == 0
   end
   v = 2
   for n = 1, #c_ do
       tmp = 20
       if c_[v + 1] then
           tmp = 19
       end
       for m = 1, tmp do
           reward_count = reward_count + 1
           tmp = table_location[reward_count]
           if tmp then
               doAddContainerItem(c_[v], tmp[1], tmp[2])
               weight = weight + getItemWeightById(tmp[1], tmp[2])
           else
               break
           end
       end
       v = v + 1
   end

   if doPlayerAddItemEx(cid, c_[2], false) == RETURNVALUE_NOERROR then
       doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You have found a " .. getItemNameById(c_[1]) .. " weighing ".. string.format("%.2f", weight) .." oz.")
       return true
   else
       local cap = getPlayerFreeCap(cid)
       if cap < weight then
           doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Require " .. string.format("%.2f", weight - cap) .. " more capacity to receive this reward weighing ".. string.format("%.2f", weight) .." oz.")
       else
           doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You require more inventory space to receive this reward.")
       end
   end
   return false
end

I know this should be the guide to change my script
Code:
local function giveReward(cid, table_location)
   local milliseconds = os.mtime()
   local item_count_in_table = #table_location
.
.
doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You have found a " .. getItemNameById(c_[1]) .. " weighing ".. string.format("%.2f", weight) .." oz.\nUnique items in table: " .. item_count_in_table .. ". Function took " .. (os.mtime() - milliseconds)/1000 .. " seconds to complete.")

But it will take me too long to figure out how to merge it with my script. It is possible that you can give me a sample that works? Merging it with my script, or doing from scratch if you consider that it needs to. For example:
  • Receive reward from the chest, with the time cooldown, and teleport player out after picking the reward
  • The reward can be (A) a bag with a sword, a mace, an axe, a bow, etc. and (B) a bag with 10-100 gold coins (math random), 2 talons, 4 ham
  • Give a chance to obtain bag (A) or bag (B) and test if chances, math.randoms, containers, etc. start working
If you can do, this will help me to know how to correctly place the loots, chances, item ammounts, and math randoms.

Thanks for helping me again,
ralke
Try this.
Lua:
-- Time Chest by Limos
local failPos = {x = 1156, y = 1090, z = 14}
local cooldownStorage = 39001
local config = {
    level = 50 -- minimum level to open the chest
}

local rewarditems = {
    [{50, 99}] = {
        rewards = {
            {id = 2472, chance =  5, countMin = 1, countMax = 1},
            {id = 2470, chance = 10, countMin = 1, countMax = 1},
            {id = 2157, chance = 15, countMin = 1, countMax = 1},
            {id = 2160, chance = 70, countMin = 1, countMax = 5}
        }
    },
    [{100, 149}] = {
        rewards = {
            {id = 2472, chance =  5, countMin = 1, countMax = 1},
            {id = 2470, chance = 10, countMin = 1, countMax = 1},
            {id = 2157, chance = 15, countMin = 1, countMax = 1},
            {id = 2160, chance = 70, countMin = 1, countMax = 5}
        }
    },
    [{150, 200}] = {
        rewards = {
            {id = 2472, chance =  5, countMin = 1, countMax = 1},
            {id = 2470, chance = 10, countMin = 1, countMax = 1},
            {id = 2157, chance = 15, countMin = 1, countMax = 1},
            {id = 2160, chance = 70, countMin = 1, countMax = 5}
        }
    },
    [{200, 10000}] = {
        rewards = {
            {id = 2472, chance =  5, countMin = 1, countMax = 1},
            {id = 2470, chance = 10, countMin = 1, countMax = 1},
            {id = 2157, chance = 15, countMin = 1, countMax = 1},
            {id = 2160, chance = 70, countMin = 1, countMax = 5}
        }
    }
}

function onUse(cid, item, fromPosition, itemEx, toPosition)
    local playerLevel = getPlayerLevel(cid)
    if playerLevel < config.level then
        doSendMagicEffect(getThingPos(cid), CONST_ME_POFF)
        doPlayerSendCancel(cid, "You need to be level "..config.level.." to open the chest.")
        return true
    end
    
    -- cooldown
    local cur_time = os.time()
    local cooldown = getPlayerStorageValue(cid, cooldownStorage)
    if cooldown > cur_time then
        doSendMagicEffect(failPos, CONST_ME_POFF)
        doPlayerSendCancel(cid, "[Boss Room] You can try open the chest again in " .. os.date('!%H:%M:%S minutes.', (cooldown - cur_time)))
        doTeleportThing(cid, failPos)
        doSendMagicEffect(failPos, CONST_ME_CRAPS)
        return true
    end
    setPlayerStorageValue(cid, cooldownStorage, cur_time + 5)
    
    local rewardList = {}
    for v, x in pairs(rewarditems) do
        if playerLevel <= v[2] and playerLevel >= v[1] then
            for i = 1, #rewarditems[v].rewards do
                if math.random(100) <= rewarditems[v].rewards[i].chance then
                    local randAmount = math.random(rewarditems[v].rewards[i].countMin, rewarditems[v].rewards[i].countMax)
                    table.insert(rewardList, {rewarditems[v].rewards[i].id, randAmount})
                end
            end
        end
    end
    
    giveItemsFromTable(cid, rewardList)
    return true
end
 
@Xikini Thanks a lot!!!! Its finally working :cool:

bagtest.png

Used this table to test, with Ghazbaran loot based on this
Lua:
    [{100, 149}] = {
        rewards = {
            {id = 6500, chance = 100, countMin = 1, countMax = 1}, --- demonic essence
            {id = 2152, chance = 100, countMin = 11, countMax = 40}, ---platinum coin
            {id = 2143, chance = 100, countMin = 1, countMax = 8}, ---- white pearl
            {id = 2470, chance = 50, countMin = 1, countMax = 1}, ---- golden legs
            {id = 2145, chance = 50, countMin = 2, countMax = 5},  ---- small diamond
            {id = 6553, chance = 33, countMin = 1, countMax = 1}, ---- ruthless axe
            {id = 8902, chance = 33, countMin = 1, countMax = 1}, ---- spellbook of mind control
            {id = 8904, chance = 33, countMin = 1, countMax = 1}, ---- Spellscroll of Prophecies
            {id = 2144, chance = 16, countMin = 5, countMax = 5}, ---- black pearl
            {id = 7428, chance = 16, countMin = 1, countMax = 1}, ---- bonebreaker
            {id = 2393, chance = 16, countMin = 1, countMax = 1}, ---- giant sword
            {id = 7405, chance = 16, countMin = 1, countMax = 1}, ---- havoc blade
            {id = 2472, chance = 16, countMin = 1, countMax = 1}  ---- mpa
        }
    },

Thread 100% solved
Regards!
 
@Xikini Thanks a lot!!!! Its finally working :cool:

View attachment 54018

Used this table to test, with Ghazbaran loot based on this
Lua:
    [{100, 149}] = {
        rewards = {
            {id = 6500, chance = 100, countMin = 1, countMax = 1}, --- demonic essence
            {id = 2152, chance = 100, countMin = 11, countMax = 40}, ---platinum coin
            {id = 2143, chance = 100, countMin = 1, countMax = 8}, ---- white pearl
            {id = 2470, chance = 50, countMin = 1, countMax = 1}, ---- golden legs
            {id = 2145, chance = 50, countMin = 2, countMax = 5},  ---- small diamond
            {id = 6553, chance = 33, countMin = 1, countMax = 1}, ---- ruthless axe
            {id = 8902, chance = 33, countMin = 1, countMax = 1}, ---- spellbook of mind control
            {id = 8904, chance = 33, countMin = 1, countMax = 1}, ---- Spellscroll of Prophecies
            {id = 2144, chance = 16, countMin = 5, countMax = 5}, ---- black pearl
            {id = 7428, chance = 16, countMin = 1, countMax = 1}, ---- bonebreaker
            {id = 2393, chance = 16, countMin = 1, countMax = 1}, ---- giant sword
            {id = 7405, chance = 16, countMin = 1, countMax = 1}, ---- havoc blade
            {id = 2472, chance = 16, countMin = 1, countMax = 1}  ---- mpa
        }
    },

Thread 100% solved
Regards!
You have a couple of things missing. xD
 
Back
Top