plsbx
plsbx

Reputation: 11

Table keys and values in Lua - don't know how

I want make dynamic player table with two pieces of information. The player's SteamID, provided as a string, would be used as the key, and the value should be a number.

Should look like table = { "ExampleSteamID" = 3, "ExampleSteamID2" = 4 }

I found something like table.insert(table, { key = x, value = z}), but it did not work.

gameevent.Listen("player_connect")

local function AdminBotOnJoinCheck(data)
    local ply = data.networkid -- SteamID of joining player
    local tableisempty = true -- some random stuff
    for k, tableply in pairs(adminbot_players) do --checking for players already writed to table, maybe need fix
        if not ply == tableply then
            --need code here
            MsgC("\nAdminBot: Player table updated | ", ply, "\n")
        end
        tableisempty = false --clear table = table break - just dont execute code. 
    end
    if tableisempty == true then
        --here same code
        MsgC("\nAdminBot: Player table updated | ", ply, "\n")
    end
    if file.Exists("adminbotplayers.txt", "DATA") == true and adminbot_teamkills_use_file == true then -- Random stuff for file writing
        local adminbot_players_json = util.TableToJSON(adminbot_players)
        file.Write("adminbotplayers.txt", adminbot_players_json)
    end
end

Upvotes: 1

Views: 2913

Answers (5)

Mischa
Mischa

Reputation: 1333

So if I correctly understand what you want to get...

You want to count each players teamkills and also want this value to be persistent.
Your approach however is not very ideal. The teamkill counter should be part of the player. This also would simplify and shorten your code.

Here is an example how you could do that.

-- You want to run this ASAP after the server is started and the world loaded

local playerMeta = FindMetaTable( "Player" ) -- get the meta table for player

function playerMeta:AddTeamkill() -- this function will increase the counter
    local teamkills = self:GetPData("teamkills", 0)
    self:SetPData("teamkills", teamkills + 1)
end

function playerMeta:GetTeamkills() -- this function will return the current counter
    return self:GetPData("teamkills", 0)
end

-- Feel free to add more functions here... Maybe a 'SetTeamkills' or 'ResetTeamkills'

You can then use it like this:

-- Add a teamkill
local player_that_teamkilled = player.GetByID(1) -- you obviously would get the player a different way...
player_that_teamkilled:AddTeamkill()

-- Get teamkills
local somePlayer = player.GetByID(1) -- same as above
somePlayer:GetTeamkills()

You do not have to mess with code for loading and saving the counter. You also don't have information related to players sitting in a different table. This means you don't have to keep track of which line in the table belongs to who. And this means, you do not have to search in a (probably huge) table for the correct line to just modify (or read) one number.

The counter will be saved into the sv.db or if you run this code on a client (which you should not do) in cl.db

Please note: You have to sync the counter to the client manually, which shouldn't be a big deal.

Further reading:
FindMetaTable()
Player:GetPData()
Player:SetPData()

Upvotes: 0

Vyacheslav Napadovsky
Vyacheslav Napadovsky

Reputation: 907

This line has incorrect Lua syntax

table = { "ExampleSteamID" = 3, "ExampleSteamID2" = 4 }

The correct way:

table = { ["ExampleSteamID"] = 3, ["ExampleSteamID2"] = 4 }

Simplified version of your code (I hope I got the idea right)

adminbot_players = {}
local function AdminBotOnJoinCheck(data)
    local ply = data.networkid
    adminbot_players[ply] = { ["ExampleSteamID"] = 3, ["ExampleSteamID2"] = 4 };
    MsgC("\nAdminBot: Player table updated | ", ply, "\n");
    if file.Exists("adminbotplayers.txt", "DATA") and adminbot_teamkills_use_file then
        file.Write("adminbotplayers.txt", util.TableToJSON(adminbot_players))
    end
end

Upvotes: 0

plsbx
plsbx

Reputation: 11

I found other way to do that using "table.insert". I made custom ID for player used to search values for selected player. Unfortunately i used two tables, but it's easier to do.
Little schema:

  • Search for player. If exist save table number to varliable.
  • Add new player if doesn't exist. Also save number
  • Add value for other table with same ID.

Thank you for answers. It was helpful :)

Upvotes: 0

Basilio German
Basilio German

Reputation: 1819

So you basically want to add a new player to the already existing table. If so, then it is this simple:

theTable[key] = value

In your case, if the steam ID is stored in ply, then we just need to add your value to the table adminbot_players with the key ply. In which case it would be:

adminbot_players[ply] = 5

Upvotes: 3

Vyacheslav
Vyacheslav

Reputation: 27221

To append a new key use this: table[newkey] = newvalue

you have got an incorrect implementation for unique values:

local yourwantedkeydefinedsomewhere = "yourwantedkeydefinedsomewhere"
local found = false
for k, tableply in pairs(adminbot_players) do --checking for players already writed to table, maybe need fix
           if ply == tableply then
                  found = true
                     break
            end
           tableisempty = false --clear table = table break - just dont execute code. 
    end

       if not found then
            adminbot_players[yourwantedkeydefinedsomewhere] = ply
            MsgC("\nAdminBot: Player table updated | ", ply, "\n")
       end

in your case for k,table ... loop any tested key will be defined as a unique.

Upvotes: 1

Related Questions