This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Wergat's profile picture

Table to NBT converter

Started by Wergat, 18 September 2015 - 10:53 PM
Wergat #1
Posted 19 September 2015 - 12:53 AM
Hello!

Lately i was doing a lot with commands, and to be able to generate more complex commands i run into some troubles with the NBT. So i wrote a small function to convert any table to NBT, to create more complicated commands. You will find the code at the bottom of this post. The function also sorts the NBT for you, so it is easy to debug if something goes wrong. This function is relatively sensible, but works well once feed it with a table. There are some really specific NBT-things you might encounter. There is a work-around possible with this function, but i could not find an example for this yet.

How to use:

Summons a creeper with a custom name

local data = {["CustomName"] = "Creepy Creature",["CustomNameVisible"] = 1}
local NBTdata = convertTableToNBT(data)
local cmd = "summon Creeper ~ ~2 ~ "..NBTdata
local success,answer = commands.exec(cmd)

Summons a zombie with a diamond pickaxe as weapon and full leather armor.

local data = {
["CustomName"] = "Fancy Zombie",
["CustomNameVisible"] = 1,
["Equipment"] = {
  {["id"] = 278,["count"] = 1},
  {["id"] = 301,["count"] = 1},
  {["id"] = 300,["count"] = 1},
  {["id"] = 299,["count"] = 1},
  {["id"] = 298,["count"] = 1}
}
}
local NBTdata = convertTableToNBT(data)
local cmd = "summon Zombie ~ ~2 ~ "..NBTdata
local success,answer = commands.exec(cmd)

Function code:

-- Input: Table of choice
-- Output: Given table converted to NBT as string useable for commands
-- Made by Wergat

function convertTableToNBT(t)
local function tableToNBT(t)
  local nbt = ""
  for k,v in pairs(t) do
   if(type(v)~="table")then
	if(t[1]==nil)then
	 if(type(v)~="string")then
	  nbt = nbt..k..":"..v..","
	 else
	  nbt = nbt..k..":\""..v.."\","
	 end
	else
	 if(type(v)~="string")then
	  nbt = nbt..v..","
	 else
	  nbt = nbt..v..","
	 end
	end
   end
  end
  for k,v in pairs(t) do
   if(type(v)=="table")then
	if(v[1]~=nil)then
	 nbt = nbt..k..":["..string.sub(tableToNBT(v),1,-2).."],"
	else
	 if(type(k)~="number")then
	  nbt = nbt..k..":{"..string.sub(tableToNBT(v),1,-2).."},"
	 else
	  nbt = nbt.."{"..string.sub(tableToNBT(v),1,-2).."},"
	 end
	end
   end
  end
  return nbt
end
return "{"..string.sub(tableToNBT(t),1,-2).."}"
end

Want it shorter? pastebin get BVLQAiEj
Lyqyd #2
Posted 19 September 2015 - 01:06 AM
Isn't this what the textutils.serializeJSON function is for?
Wergat #3
Posted 19 September 2015 - 01:52 AM
There is a difference.

convertTableToNBT:
{CustomName:"Armoured Zombie",CustomNameVisible:1,Equipment:[{id:278,count:1},{id:301,count:1},{id:300,count:1},{id:299,count:1},{id:298,count:1}]}

textutils.serializeJSON:
{"CustomName":"Armoured Zombie","CustomNameVisible":1,"Equipment":[{"id":278,"count":1},{"id":301,"count":1},{"id":300,"count":1},{"id":299,"count":1},{"id":298,"count":1}]}