2016-10-12 5 views
1

Я хочу сделать динамический стол с двумя частями информации. В качестве ключа будет использоваться SteamID игрока, предоставляемый как строка, и значение должно быть числом.Табличные ключи и значения в Lua - не знаю, как

должно выглядеть table = { "ExampleSteamID" = 3, "ExampleSteamID2" = 4 }

я нашел что-то вроде table.insert(table, { key = x, value = z}), но это не сработало.

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 
+0

Я хотел бы призвать вас читать [Программирование в Lua] (https://www.lua.org/pil/contents.html), спереди назад - глава 2.5 будет очень полезна для вас. Изучите также справочное руководство, особенно разделы [таблицы] (https://www.lua.org/manual/5.1/manual.html#2.5.7) и их [манипуляции] (https: // www. lua.org/manual/5.1/manual.html#5.5). – Oka

+0

Я не могу использовать «:: =» в скрипте для сервера gmod:/ – plsbx

+0

':: =' является частью [BNF] (https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form), нотация, используемая для _describe_ синтаксиса Lua, то есть «определяется как». '=' используется для назначения на языке. – Oka

ответ

2

Таким образом, вы в основном хотите добавить нового игрока в уже существующую таблицу. Если это так, то это просто:

theTable[key] = value 

В вашем случае, если пара ID хранится в ply, то нам просто нужно добавить значение в таблицу adminbot_players с ключом ply. В этом случае было бы:

adminbot_players[ply] = 5 
+0

Table.insert работает только с числовыми индексами, не имеет смысла использовать вставку в словаре – warspyking

+0

Вы правы. Обновленный код. –

1

Для добавления нового ключа использовать это: table[newkey] = newvalue

вы получили неправильную реализацию уникальных значений:

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 

в вашем случае for k,table ... петли любой проверенный ключ будет определен как уникальный.

0

Я нашел другой способ сделать это с помощью «table.insert». Я сделал пользовательский идентификатор для игрока, используемого для поиска значений для выбранного игрока. К сожалению, я использовал две таблицы, но это проще сделать.
Маленькая схема:

  • Поиск игрока. Если существует, сохраните номер таблицы в varliable.
  • Добавить нового игрока, если он не существует. Также сохранить номер
  • Добавить значение для другой таблицы с тем же идентификатором.

Благодарим за ответы. Это было полезно :)

0

Эта строка имеет неправильный синтаксис Lua

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

Правильный путь:

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

Упрощенная версия кода (я надеюсь, что у меня появилась идея справа)

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 
0

Итак, если я правильно понимаю, что вы хотите получить ...

Вы хотите, чтобы подсчеты каждого игрока команды, а также хотите, чтобы это значение было постоянным.
Ваш подход, однако, не очень идеален. Счетчик teamkill должен быть частью игрока. Это также упростит и сократит ваш код.

Вот пример, как вы могли это сделать.

-- 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' 

Вы можете использовать его как это:

-- 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() 

Вам не придется возиться с кодом для загрузки и сохранения счетчика. У вас также нет информации, связанной с игроками, сидящими в другом столе. Это означает, что вам не нужно отслеживать, какая строка в таблице принадлежит кому. И это означает, что вам не нужно искать в (возможно, огромной) таблице правильную строку, чтобы просто изменить (или прочитать) один номер.

Счетчик будет сохранен в sv.db или если вы запустите этот код на клиенте (который вы должны не делать) в cl.db

Пожалуйста, обратите внимание: Вы должны синхронизировать счетчик клиента вручную, что не должно быть большой проблемой.

Дальнейшее чтение:
FindMetaTable()
Player:GetPData()
Player:SetPData()