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

GlobalEvent Record reward. TFS 1.2

Mkalo

ボーカロイド
Senator
Joined
Jun 1, 2011
Messages
1,118
Solutions
55
Reaction score
946
Location
Japan
Code:
local function itemId(x)
    if not x then
        print("[Warning - createItems] Missing itemid or name in table to create.")
    elseif type(x) == "number" then
        return x
    elseif type(x) == "string" then
        local itemType = ItemType(x)
        if itemType and itemType:getId() ~= 0 then
            return itemType:getId()
        else
            print("[Warning - createItems] Item with name " .. x .. " not found.")
        end
    end
    return false
end

function createItems(items)
    local ret = {}
    for _, item in ipairs(items) do
        local id = itemId(item.id or item.name)
        if id then
            local obj = Game.createItem(id, item.count or 1)
            if item.items then
                local itemType = ItemType(id)
                if itemType:isContainer() then
                    local _items = createItems(item.items)
                    if _items then
                        for i = 1, #_items do
                            obj:addItemEx(_items[i])
                        end
                    end
                end
            end
            table.insert(ret, obj)
        end
    end
    return ret
end

local function pushSeparated(buffer, sep, ...) -- made by Non Sequitur aka Socket aka Cezar
    local argv = {...}
    local argc = #argv
    for k, v in ipairs(argv) do
        table.insert(buffer, v)
        if k < argc and sep then
            table.insert(buffer, sep)
        end
    end
end

local function insertItems(buffer, info, parent, items) -- made by Non Sequitur aka Socket aka Cezar
    local start = info.running
    for _, item in ipairs(items) do
        if _ ~= 1 or parent > 100 then
            table.insert(buffer, ",")
        end

        info.running = info.running + 1
        table.insert(buffer, "(")
        pushSeparated(buffer, ",", info.playerGuid, parent, info.running, item:getId(), item:getSubType(), db.escapeBlob(""))
        table.insert(buffer, ")")

        if item:isContainer() then
            local size = item:getSize()
            if size > 0 then
                local subItems = {}
                for i = 1, size do
                    table.insert(subItems, item:getItem(i - 1))
                end

                insertItems(buffer, info, info.running, subItems)
            end
        end
    end
    return info.running - start
end

function Player:sendInboxItems(items)
    local inbox = self:getInbox()
    local itemstable = createItems(items)
    if #itemstable > 0 then
        for i = #itemstable, 1, -1 do
            inbox:addItemEx(itemstable[i], INDEX_WHEREEVER, FLAG_NOLIMIT)
        end
        return true
    end
end

function sendInboxItemsOffline(guid, items)
    local itemstable = createItems(items)
    if #itemstable > 0 then
        db.asyncStoreQuery("SELECT MAX(`sid`) as `sid` FROM `player_inboxitems` WHERE `player_id` = " .. guid,
        function(query)
            local lastStoreId
            if query then
                lastStoreId = result.getDataInt(query, "sid")
            end

            local info = {
                playerGuid = guid,
                running = lastStoreId ~= 0 and lastStoreId or 100
            }
            local buffer = {'INSERT INTO `player_inboxitems` (`player_id`, `pid`, `sid`, `itemtype`, `count`, `attributes`) VALUES'}
            local total = insertItems(buffer, info, 0, createItems(items))
            table.insert(buffer, ";")
            db.query(table.concat(buffer))
        end)
    end
end

local first_reward = {
    [1] = {id=1987, items={{id=2470}}},
    [2] = {name="magic plate armor"},
    [3] = {id=2160, count=3},
}

local config = { --[record] {amount of points}
    accountTable = "accounts", -- if your db is not named account
    pointsColumn = "premium_points", -- in accountTable
    accIdColumn = "account_id", -- in players
    [50] = {points = 100, items = first_reward, offlinelevel = 50, offlineitems = true, offlinepoints = true}, -- All players online + Offlines(level 50+) will receive points and items
    [100] = {points = 200}, -- Only online players will receive 200 points.
}


function onRecord(current, old)
    -- Async Query.
    if config[current] then
        db.asyncStoreQuery("SELECT `id` FROM `" .. config.accountTable .. "`",
        function(query)
            if query then
                repeat
                    local id = result.getDataInt(query, "id")
                    local playersQuery = db.storeQuery("SELECT * FROM `players` WHERE `" .. config.accIdColumn .. "` = " .. id)
                    local players = {}
                    repeat
                        if result.getDataInt(playersQuery, "id") then
                            table.insert(players, {result.getString(playersQuery, "name"), result.getDataInt(playersQuery, "level"), result.getDataInt(playersQuery, "id")})
                        end
                    until not result.next(playersQuery)
                    if #players > 0 then
                        local highestlvl, highestid = 0
                        local added = false
                        for i = 1, #players do
                            if players[i][2] > highestlvl then
                                highestlvl = players[i][2]
                                highestid = i
                            end
                            local player = Player(players[i][1])
                            if player then
                                added = true
                                if config[current].items then
                                    player:sendInboxItems(config[current].items)
                                end
                                if config[current].points then
                                    db.query("UPDATE `" .. config.accountTable .. "` SET `" .. config.pointsColumn .. "` = `" .. config.pointsColumn .. "` + " .. config[current].points .. " WHERE `id` = " .. id)
                                end
                                break
                            end
                        end
                        if not added and ((not config[current].offlinelevel) or (players[highestid][2] >= config[current].offlinelevel)) then
                            if config[current].items then
                                if config[current].offlineitems then
                                    sendInboxItemsOffline(players[highestid][3], config[current].items)
                                end
                            end
                            if config[current].points then
                                if config[current].offlinepoints then
                                    db.query("UPDATE `" .. config.accountTable .. "` SET `" .. config.pointsColumn .. "` = `" .. config.pointsColumn .. "` + " .. config[current].points .. " WHERE `id` = " .. id)
                                end
                            end
                        end
                    end
                until not result.next(query)
            end
        end)
    end

    -- Messages
    if (config[current]) then
        local msg = "The server has reached a new record with "..current.." players online"
        if config[current].points or config[current].items then
            msg = msg .. ", all players online received:"
            if config[current].points then
                msg = msg .. " " .. config[current].points .. " points"
            end
            if config[current].items then
                msg = msg .. (config[current].points and " and some items in the inbox" or " some items in the inbox")
            end

        end
        addEvent(Game.broadcastMessage, 150, msg .. ".", MESSAGE_EVENT_ADVANCE)

    else
        addEvent(Game.broadcastMessage, 150, "New record: " .. current .. " players are logged in.", MESSAGE_STATUS_DEFAULT)
    end

    return true
end

Every option in config is optional, you can use any combination you prefer for each reward.
Table with items should be configured as "first_reward", you can have how many containers inside containers as long as you keep the same pattern.
Items are sent to the highest level of the account when the account has no character online

[50] = {points = 100, items = first_reward, offlinelevel = 50, offlineitems = true, offlinepoints = true},

offlinelevel - Account that is offline must have atleast one character above this level (optional)
offlineitems - Send items to offline characters.
offlinepoints - Add points to offline characters.

The others are self explanatory.

Credits @Printer: https://otland.net/threads/new-record-all-players-recive-premium-points.201543/
 
Last edited:
Back
Top