[OTS] Lists of unique numbers kept in ‘player storage’

Friend asked me about code to keep ‘auto loot lists’ in storage. So player can configure few lists of items and then just switch between them, when he goes to other spawn with different loot.

-- config
local listsStartStorage = 550000000
local maximumListsCount = 10
local maximumElementsPerList = 100

-- variables for calculations
local listOffset = maximumElementsPerList + 1

function lists_getLists(player)
    local result = {}
    for i = 1, maximumListsCount do
        result[i] = lists_getListElementsCount(player, i)
    end

    return result
end

function lists_getListElementsCount(player, listId)
    local startStorage = listsStartStorage + listOffset * listId
    return math.max(0, player:getStorage(startStorage))
end

function lists_getListElements(player, listId)
    local result = {}
    local startStorage = listsStartStorage + listOffset * listId
    local listElementsCount = lists_getListElementsCount(player, listId)
    for i = startStorage + 1, startStorage + listElementsCount do
        table.insert(result, player:getStorage(i))
    end

    return result
end

function lists_removeAllListElements(player, listId)
    local startStorage = listsStartStorage + listOffset * listId
    local listElementsCount = lists_getListElementsCount(player, listId)
    for i = startStorage + 1, startStorage + listElementsCount + 1 do
        player:setStorage(i, -1)
    end
    player:setStorage(startStorage, -1)
end

function lists_getListElement(player, listId, elementKey)
    local elementStorage = listsStartStorage + listOffset * listId + elementKey
    return player:getStorage(elementStorage)
end

local function lists_assertListId(listId)
    assert(listId >= 1, 'minimum list id is 1')
    assert(listId <= maximumListsCount, 'maximum list id is 1' .. maximumListsCount)
end

local function lists_assertElementKey(elementKey)
    assert(elementKey >= 1, 'minimum list element id is 1')
    assert(elementKey <= maximumElementsPerList, 'maximum list element id is ' .. maximumElementsPerList)
end

-- this is for internal use only, should not be used by user
local function lists_setListElement(player, listId, elementKey, elementValue)
    lists_assertListId(listId)
    lists_assertElementKey(elementKey)
    local elementStorage = listsStartStorage + listOffset * listId + elementKey
    player:setStorage(elementStorage, elementValue)
end

-- this is for internal use only, should not be used by user
local function lists_setListElementsCount(player, listId, count)
    lists_assertListId(listId)
    lists_assertElementKey(count)
    local startStorage = listsStartStorage + listOffset * listId
    player:setStorage(startStorage, count)
end

function lists_addListElement(player, listId, elementValue)
    local elements = lists_getListElements(player, listId)
    for k, v in pairs(elements) do
        if v == elementValue then
            return
        end
    end

    local elementsCount = lists_getListElementsCount(player, listId)
    lists_setListElement(player, listId, elementsCount + 1, elementValue)
    lists_setListElementsCount(player, listId, elementsCount + 1)
end

function lists_removeListElement(player, listId, elementValue)
    local elements = lists_getListElements(player, listId)
    local elementToRemovePosition = nil
    for k, v in pairs(elements) do
        if v == elementValue then
            elementToRemovePosition = k
            break
        end
    end

    if elementToRemovePosition then
        local elementsCount = lists_getListElementsCount(player, listId)
        for i = elementToRemovePosition + 1, elementsCount  do
            local nextElementValue = lists_getListElement(player, listId, i)
            lists_setListElement(player, listId, i - 1, nextElementValue)
        end
        lists_setListElement(player, listId, elementsCount, -1)
        lists_setListElementsCount(player, listId, elementsCount - 1)
    end
end

TESTS:

Player = {}
function Player:new()
    o = {storages = {}}
    setmetatable(o, self)
    self.__index = self
    return o
end

function Player.getStorage(self, k)
    if (self.storages[k]) then
        return self.storages[k]
    end
    return -1
end

function Player.setStorage(self, k, v)
    if (v == -1) then
        v = nil
    end
    self.storages[k] = v
end

function Player.dumpStorages(self)
    local storages = 'storages: '
    for k, v in pairs(self.storages) do
        storages = storages .. k .. '=' .. v .. ', '
    end
    print(storages)
end

local function printPlayerListsElementsCount(player)
    local playerLists = lists_getLists(player)
    for k, v in pairs(playerLists) do
        local listElementsString = ''
        for k2, v2 in pairs(lists_getListElements(player, k)) do
            listElementsString = listElementsString .. ' ' .. k2 .. '=' .. v2 .. ', '
        end
        print ('list', k, 'elements', v, 'values', listElementsString)
    end
end

player = Player:new()

print()
player:dumpStorages()
print('start - empty list')
printPlayerListsElementsCount(player)

print()
player:dumpStorages()
lists_addListElement(player, 2, 2001)
lists_addListElement(player, 2, 2002)
print('added 2 elements to list 2')
player:dumpStorages()
printPlayerListsElementsCount(player)

print()
player:dumpStorages()
lists_addListElement(player, 1, 1001)
lists_addListElement(player, 1, 1002)
lists_addListElement(player, 1, 1003)
lists_addListElement(player, 1, 1004)
lists_addListElement(player, 1, 1005)
print('added 5 elements to list 1')
player:dumpStorages()
printPlayerListsElementsCount(player)

print()
player:dumpStorages()
lists_removeListElement(player, 1, 1001)
print('removed first element from list 1')
player:dumpStorages()
printPlayerListsElementsCount(player)

print()
player:dumpStorages()
lists_removeListElement(player, 1, 1005)
print('removed last element from list 1')
player:dumpStorages()
printPlayerListsElementsCount(player)

print()
player:dumpStorages()
lists_removeListElement(player, 1, 1003)
print('removed middle element from list 1')
player:dumpStorages()
printPlayerListsElementsCount(player)

print()
player:dumpStorages()
lists_removeAllListElements(player, 1)
print('removed all elements from list 1')
player:dumpStorages()

You can paste code and tests to online tool like: https://www.tutorialspoint.com/execute_lua_online.php

Leave a Reply

Your email address will not be published. Required fields are marked *