• 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 [OTX 2] Simple Reward System

potinho

Advanced OT User
Joined
Oct 11, 2009
Messages
1,493
Solutions
17
Reaction score
187
Location
Brazil
Hey everyone, I'm trying to create a simple reward system where predefined rewards with fixed chances are distributed to players within the boss's line of sight (the value is also defined). However, I've been experiencing issues such as rewards being sent incorrectly, bosses dying and not delivering rewards (sometimes), or players dying and just being teleported. Could you help me improve the code?

<event type="death" name="SpecificReward" event="script" value="Reward System/reward_specific.lua"/>

LUA:
REWARD_FIXED = {
    rewardBagId = 2595,
    town_id = 1,

    bosses = {
        ["minkek"] = { -- em minúsculo
            rangeView = {x = 15, y = 13},
            loot = {
                {2160, 10, 100000, true},       -- 100%, todos recebem
                {6326, 1, 50000, false, 1},     -- 50%, 1 jogador
                {5164, 1, 1000, false, 2},      -- 1%, até 2 jogadores
                {2152, 10, 500, false, 1},      -- 0.5%, 1 jogador
            }
        },
        ["undertaker"] = {
            rangeView = {x = 20, y = 15},
            loot = {
                {2152, 100, 100, true},         -- 100%, todos recebem
                {2173, 1, 1, false, 1},         -- 1%, 1 jogador
            }
        }
    }
}


LUA:
dofile('data/sistemas/specificreward.lua')

local bossDeathTimers = {}

local function isValidPlayer(uid)
    return isPlayer(uid) and not isPlayerGhost(uid)
end

local function sendReward(uid, bossName, rewardList, playerNameFallback)
    if #rewardList == 0 then return end

    local chest = doCreateItemEx(REWARD_FIXED.rewardBagId)
    doItemSetAttribute(chest, "description", "Reward from ".. bossName ..".")

    local msg = "The following items are available in your reward chest:"

    for _, entry in ipairs(rewardList) do
        local itemid, count = entry[1], entry[2]
        if doAddContainerItem(chest, itemid, count) then
            msg = msg .. " " .. (count > 1 and count or "") .. " " .. getItemNameById(itemid) .. ","
        end
    end

    msg = msg:gsub(",$", ".")

    if uid > 0 and isValidPlayer(uid) then
        local playerName = getPlayerName(uid)
        local playerPos = getPlayerPosition(uid)

        doPlayerSendMailByName(playerName, chest, REWARD_FIXED.town_id)
        doPlayerSendTextMessage(uid, MESSAGE_INFO_DESCR, msg)
        doSendMagicEffect(playerPos, CONST_ME_MAGIC_BLUE)
    else
        doPlayerSendMailByName(playerNameFallback or "", chest, REWARD_FIXED.town_id)
    end
end


local function rewardChestSystem(bossName, pos)
    local boss = REWARD_FIXED.bosses[bossName:lower()]
    if not boss then return end

    local playersInRange = {}
    local spectators = getSpectators(pos, boss.rangeView.x, boss.rangeView.y, false) or {}

    for _, uid in ipairs(spectators) do
        if isValidPlayer(uid) then
            table.insert(playersInRange, getPlayerName(uid))
        end
    end

    if #playersInRange == 0 then return end

    local rewards = {}
    for _, name in ipairs(playersInRange) do
        rewards[name] = {}
    end

    for _, loot in ipairs(boss.loot) do
        local itemid, count, chance, shared, maxWinners = loot[1], loot[2], loot[3], loot[4], loot[5] or 1

        if math.random(100000) <= chance then
            if shared then
                for _, name in ipairs(playersInRange) do
                    table.insert(rewards[name], {itemid, count})
                end
            else
                local available = {}
                for _, name in ipairs(playersInRange) do
                    table.insert(available, name)
                end

                for i = 1, math.min(maxWinners, #available) do
                    if #available > 0 then
                        local idx = math.random(#available)
                        local winner = available[idx]
                        table.insert(rewards[winner], {itemid, count})
                        table.remove(available, idx)
                    end
                end
            end
        end
    end

    for name, rewardList in pairs(rewards) do
        if #rewardList > 0 then
            local uid = getPlayerByName(name)
            sendReward(uid or 0, bossName, rewardList)
        end
    end
end

function onDeath(cid, corpse, killer)
    local bossName = getCreatureName(cid):lower()
    local boss = REWARD_FIXED.bosses[bossName]

    if boss then
        rewardChestSystem(bossName, getThingPos(cid))
    end
    return true
end
 
Back
Top