• 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.X+ Check x players for x storage? TFS 1.3

Mjmackan

Mapper ~ Writer
Premium User
Joined
Jul 18, 2009
Messages
1,424
Solutions
15
Reaction score
176
Location
Sweden
How to check players in X area for Y storage and then print the player with the highest amount of that storage in lua?
I need the player id, since i want to print the name of the player and the amount he has in Y storage.
TFS 1.3

I tried to use something like this..
Lua:
local fightAreas = Game.getSpectators({x = 930, y = 603, z = 7}, 10, 10, true)
 if fightAreas ~= nil then
  for _, areaPlayers in pairs(fightAreas) do
   if isPlayer(areaPlayers) then
    print(areaPlayers:getStorageValue(fragEventPlayer))
end
end
end
And found this link..

I didn't succeed that great, at best i printed nil hehe.
 
Last edited:
Solution
Sorry for the slow reply, I had to get my "giving storage script" straight, that script is working now however.
I added your script and there is now 1x player with storage of 2 and 1x player with storage of 1 but its printing blank in console.
It's because the function is using return when it finds something incorrect.
return forces the script to stop prematurely, which doesn't allow the for loops to work an intended.

Have to use nested if's in loops, even tho it doesn't look pretty. xP

So I'll show the way to do the for loops correctly, for educational purposes
and also the way to do it more efficiently with getSpectators. (2nd code)
Lua:
local cfg = {
    topLeft     = Position(1, 1, 1),
    bottomRight = Position(2, 2, 2)
}...
Try this
Lua:
local cfg = {
    topLeft     = Position(1, 1, 1),
    bottomRight = Position(2, 2, 2)
}

--
local playersTable = {}
local storageKey = 123456

for z = cfg.topLeft.z, cfg.bottomRight.z do
    for y = cfg.topLeft.y, cfg.bottomRight.y do
        for x = cfg.topLeft.x, cfg.bottomRight.x do
            (function()
                local tile = Tile(x, y, z)
                if not tile then
                    return
                end

                local topCreature = tile:getTopCreature()
                if not topCreature or not topCreature:isPlayer() then
                    return
                end

                local creatureStorage = topCreature:getStorageValue(storageKey)
                if creatureStorage < 0 then
                    return
                end

                table.insert(playersTable, {topCreature:getId(), creatureStorage})
            end)()
        end
    end
end

table.sort(playersTable, function(a, b) return a[2] > b[2] end)

for i = 1, #playersTable do
    local playerId     = playersTable[i][1]
    local storageValue = playersTable[i][2]
    print(playerId, storageValue)
end
 
Try this
Lua:
local cfg = {
    topLeft     = Position(1, 1, 1),
    bottomRight = Position(2, 2, 2)
}

--
local playersTable = {}
local storageKey = 123456

for z = cfg.topLeft.z, cfg.bottomRight.z do
    for y = cfg.topLeft.y, cfg.bottomRight.y do
        for x = cfg.topLeft.x, cfg.bottomRight.x do
            (function()
                local tile = Tile(x, y, z)
                if not tile then
                    return
                end

                local topCreature = tile:getTopCreature()
                if not topCreature or not topCreature:isPlayer() then
                    return
                end

                local creatureStorage = topCreature:getStorageValue(storageKey)
                if creatureStorage < 0 then
                    return
                end

                table.insert(playersTable, {topCreature:getId(), creatureStorage})
            end)()
        end
    end
end

table.sort(playersTable, function(a, b) return a[2] > b[2] end)

for i = 1, #playersTable do
    local playerId     = playersTable[i][1]
    local storageValue = playersTable[i][2]
    print(playerId, storageValue)
end
Always use getSpectators for that task. getSpectators is highly optimized for that task and getTopCreature will miss creatures that are standing in a stack (as the function name says top creature)
 
Try this
Lua:
local cfg = {
    topLeft     = Position(1, 1, 1),
    bottomRight = Position(2, 2, 2)
}

--
local playersTable = {}
local storageKey = 123456

for z = cfg.topLeft.z, cfg.bottomRight.z do
    for y = cfg.topLeft.y, cfg.bottomRight.y do
        for x = cfg.topLeft.x, cfg.bottomRight.x do
            (function()
                local tile = Tile(x, y, z)
                if not tile then
                    return
                end

                local topCreature = tile:getTopCreature()
                if not topCreature or not topCreature:isPlayer() then
                    return
                end

                local creatureStorage = topCreature:getStorageValue(storageKey)
                if creatureStorage < 0 then
                    return
                end

                table.insert(playersTable, {topCreature:getId(), creatureStorage})
            end)()
        end
    end
end

table.sort(playersTable, function(a, b) return a[2] > b[2] end)

for i = 1, #playersTable do
    local playerId     = playersTable[i][1]
    local storageValue = playersTable[i][2]
    print(playerId, storageValue)
end
Sorry for the slow reply, I had to get my "giving storage script" straight, that script is working now however.
I added your script and there is now 1x player with storage of 2 and 1x player with storage of 1 but its printing blank in console.
 
Last edited:
Sorry for the slow reply, I had to get my "giving storage script" straight, that script is working now however.
I added your script and there is now 1x player with storage of 2 and 1x player with storage of 1 but its printing blank in console.
It's because the function is using return when it finds something incorrect.
return forces the script to stop prematurely, which doesn't allow the for loops to work an intended.

Have to use nested if's in loops, even tho it doesn't look pretty. xP

So I'll show the way to do the for loops correctly, for educational purposes
and also the way to do it more efficiently with getSpectators. (2nd code)
Lua:
local cfg = {
    topLeft     = Position(1, 1, 1),
    bottomRight = Position(2, 2, 2)
}

local playersTable = {}
local storageKey = 123456

-- this part and below goes into your main code
for z = cfg.topLeft.z, cfg.bottomRight.z do
    for y = cfg.topLeft.y, cfg.bottomRight.y do
        for x = cfg.topLeft.x, cfg.bottomRight.x do
            (function()
                local tile = Tile(x, y, z)
                if tile then   
                    local topCreature = tile:getTopCreature()
                    if topCreature and topCreature:isPlayer() then
                        local creatureStorage = topCreature:getStorageValue(storageKey)           
                        table.insert(playersTable, {topCreature:getId(), creatureStorage})
                    end
                end
            end)()
        end
    end
end

table.sort(playersTable, function(a, b) return a[2] > b[2] end)

for i = 1, #playersTable do
    local playerId     = playersTable[i][1]
    local storageValue = playersTable[i][2]
    print(playerId, storageValue)
end
Lua:
local cfg = {
    centrePosition = Position(250, 250, 7),
    xRange = 1, -- smallest size you can use is 1. do not put 0, or it's range defaults to 12.
    yRange = 1, -- (range 1 is an 'exori' 3 by 3 tiles. range 2 is 5 by 5 tiles)
    multifloor = false, -- if you need to check all floors, not only Z floor from centrePosition
    onlyPlayers = true -- set to false if you need to check creature storages as well
}

local playersTable = {}
local storageKey = 123456

-- this part and below goes into your main code
local spectators = Game.getSpectators(cfg.centrePosition, cfg.multifloor, cfg.onlyPlayers, cfg.xRange, cfg.xRange, cfg.yRange, cfg.yRange)
for i = 1, #spectators do
    local creature = spectators[i]
    local creatureStorage = creature:getStorageValue(storageKey)           
    table.insert(playersTable, {creature:getId(), creatureStorage})
end

table.sort(playersTable, function(a, b) return a[2] > b[2] end)

for i = 1, #playersTable do
    local playerId     = playersTable[i][1]
    local storageValue = playersTable[i][2]
    print(playerId, storageValue)
end
 
Solution
It's because the function is using return when it finds something incorrect.
return forces the script to stop prematurely, which doesn't allow the for loops to work an intended.

Have to use nested if's in loops, even tho it doesn't look pretty. xP

So I'll show the way to do the for loops correctly, for educational purposes
and also the way to do it more efficiently with getSpectators. (2nd code)
Lua:
local cfg = {
    topLeft     = Position(1, 1, 1),
    bottomRight = Position(2, 2, 2)
}

local playersTable = {}
local storageKey = 123456

-- this part and below goes into your main code
for z = cfg.topLeft.z, cfg.bottomRight.z do
    for y = cfg.topLeft.y, cfg.bottomRight.y do
        for x = cfg.topLeft.x, cfg.bottomRight.x do
            (function()
                local tile = Tile(x, y, z)
                if tile then  
                    local topCreature = tile:getTopCreature()
                    if topCreature and topCreature:isPlayer() then
                        local creatureStorage = topCreature:getStorageValue(storageKey)          
                        table.insert(playersTable, {topCreature:getId(), creatureStorage})
                    end
                end
            end)()
        end
    end
end

table.sort(playersTable, function(a, b) return a[2] > b[2] end)

for i = 1, #playersTable do
    local playerId     = playersTable[i][1]
    local storageValue = playersTable[i][2]
    print(playerId, storageValue)
end
Lua:
local cfg = {
    centrePosition = Position(250, 250, 7),
    xRange = 1, -- smallest size you can use is 1. do not put 0, or it's range defaults to 12.
    yRange = 1, -- (range 1 is an 'exori' 3 by 3 tiles. range 2 is 5 by 5 tiles)
    multifloor = false, -- if you need to check all floors, not only Z floor from centrePosition
    onlyPlayers = true -- set to false if you need to check creature storages as well
}

local playersTable = {}
local storageKey = 123456

-- this part and below goes into your main code
local spectators = Game.getSpectators(cfg.centrePosition, cfg.multifloor, cfg.onlyPlayers, cfg.xRange, cfg.xRange, cfg.yRange, cfg.yRange)
for i = 1, #spectators do
    local creature = spectators[i]
    local creatureStorage = creature:getStorageValue(storageKey)          
    table.insert(playersTable, {creature:getId(), creatureStorage})
end

table.sort(playersTable, function(a, b) return a[2] > b[2] end)

for i = 1, #playersTable do
    local playerId     = playersTable[i][1]
    local storageValue = playersTable[i][2]
    print(playerId, storageValue)
end
Thank you so much! Then there's only one thing left, how to print the player with the highest storage and the amount?
 
Nvm, figured it out after looking it through a bit more awake.
Glad you figured it out.

I wasn't available to help at the time, and totally forgot about this thread.
Sorry about that.
 
Glad you figured it out.

I wasn't available to help at the time, and totally forgot about this thread.
Sorry about that.
You really posted a better version of what I needed but my lazy/tired ass didn't figure it out at first, thanks Xikini for the great help!
 
Back
Top