diff options
author | Tiger Wang <ziwei.tiger@outlook.com> | 2020-07-30 18:33:31 +0200 |
---|---|---|
committer | Tiger Wang <ziwei.tiger@outlook.com> | 2020-07-30 18:33:31 +0200 |
commit | dfa2f3687c29702057417a829c9b06f9ac959ee1 (patch) | |
tree | 5c244091680a26c6de6778ec84d6b478ad0193d4 | |
parent | 1.14 connection support (diff) | |
download | cuberite-dfa2f3687c29702057417a829c9b06f9ac959ee1.tar cuberite-dfa2f3687c29702057417a829c9b06f9ac959ee1.tar.gz cuberite-dfa2f3687c29702057417a829c9b06f9ac959ee1.tar.bz2 cuberite-dfa2f3687c29702057417a829c9b06f9ac959ee1.tar.lz cuberite-dfa2f3687c29702057417a829c9b06f9ac959ee1.tar.xz cuberite-dfa2f3687c29702057417a829c9b06f9ac959ee1.tar.zst cuberite-dfa2f3687c29702057417a829c9b06f9ac959ee1.zip |
-rw-r--r-- | Tools/BlockTypePaletteGenerator/Generator.lua | 661 | ||||
-rw-r--r-- | Tools/BlockTypePaletteGenerator/ItemGenerator.lua | 222 | ||||
-rw-r--r-- | Tools/BlockTypePaletteGenerator/convert.py | 19 |
3 files changed, 737 insertions, 165 deletions
diff --git a/Tools/BlockTypePaletteGenerator/Generator.lua b/Tools/BlockTypePaletteGenerator/Generator.lua index b052ffa92..0b8dfec64 100644 --- a/Tools/BlockTypePaletteGenerator/Generator.lua +++ b/Tools/BlockTypePaletteGenerator/Generator.lua @@ -1,165 +1,496 @@ --- Generator.lua - ---[[ -Crafts an intermediate block palette format to be read by Cuberite. -It processes the blocks.json report file (https://wiki.vg/Data_Generators) -into a file that can be loaded into a BlockTypePalette (and is to be stored -as Server/Protocol/<version>/base.btp.txt). - -The output format is the regular TSV BlockTypePalette, described in the -$/src/BlockTypePalette.h file. ---]] - - - - --- Allow Lua to load libraries in our subfolder: -package.path = 'lib/lunajson/src/?.lua;' .. package.path; - - - - - - ---- Prints usage instructions to stdout. --- If the optional `aMessage` is passed, output is prepended by message _and_ --- redirected to stderr. -local function usage(aMessage) - if aMessage then - io.output(io.stderr); - io.write(aMessage, "\n\n"); - end - io.write( - "Usage: lua Generator.lua INPUTFILE OUTPUTFILE\n".. - "Converts the Minecraft blocks.json report format to the cuberite ".. - "block type palette format.\n".. - "\n".. - "INPUTFILE and OUTPUTFILE must point to a valid path. INPUTFILE must ".. - "be readable and OUTPUTFILE must be writable. Either can be replaced ".. - "with `-` (dash character) to point to standard-input or -output.\n"); - os.exit(message and 1 or 0); -end - - - - - ---- Parses the JSON registry into a Lua table ---[[ The returned array-table has the following format: -{ - { id = 1, blockTypeName = "minecraft:stone", properties = {key = value, ...} }, - ... -} ---]] -local function parseRegistry(aBlockRegistryJsonStr) - assert(type(aBlockRegistryJsonStr) == "string") - - local lj = require("lunajson") - local input = lj.decode(aBlockRegistryJsonStr) - local registry = {} - local idx = 1 - for blockTypeName, blockData in pairs(input) do - for _, state in pairs(blockData.states) do - registry[idx] = { - id = state.id, - blockTypeName = blockTypeName, - properties = state.properties, - } - idx = idx + 1 - end - end - return registry -end - - - - - ---- Serializes the properties from the JSON / array table format into a single output string --- Concatenates all properties with \t as the delimiting character -local function serializeProperties(aProperties) - local res = {} - local idx = 1 - for k, v in pairs(aProperties or {}) do - res[idx] = k - res[idx + 1] = v - idx = idx + 2 - end - return table.concat(res, "\t") -end - - - - - ---- Returns the prefix that is common for all block type names in the registry --- aRegistry is the parsed registry, as returned from parseRegistry() -local function findCommonPrefix(aRegistryTable) - local prefix = aRegistryTable[1].blockTypeName - local len = string.len(prefix) - local sub = string.sub - for _, block in ipairs(aRegistryTable) do - while (sub(block.blockTypeName, 1, len) ~= prefix) do - len = len - 1 - if (len == 0) then - return "" - end - prefix = sub(prefix, 1, len) - end - end - return prefix -end - - - - - --- Test whether the script is run in a path where it can load it's libraries -if not(pcall(function() require("lunajson") end)) then - usage( - "Could not load required libraries, please run `Generator.lua` " .. - "within its directory and make sure to run `git submodule update`." - ) -end - --- Check/Prepare CLI arguments -local inpath, outpath = ...; -inpath = inpath or "blocks.json" -outpath = outpath or "base.btp.txt" -if (inpath ~= "-") then - local handle, err = io.open(inpath, "r") - io.input(handle or usage(err)) -end -if (outpath ~= "-") then - local handle, err = io.open(outpath, "w") - io.output(handle or usage(err)) -end - --- Parse the registry: -local registry = parseRegistry(io.input():read("*a")) -local commonPrefix = findCommonPrefix(registry) - --- Sort the entries: -table.sort(registry, - function (entry1, entry2) - return (entry1.id < entry2.id) - end -) - --- Write out the output format: -io.write("BlockTypePalette\n") -io.write("FileVersion\t1\n") -io.write("CommonPrefix\t", commonPrefix, "\n") -io.write("\n") -local prefixLen = string.len(commonPrefix) + 1 -for _, entry in ipairs(registry) do - local props = serializeProperties(entry.properties) - if (props ~= "") then - props = "\t" .. props - end - io.write( - entry.id, "\t", - string.sub(entry.blockTypeName, prefixLen), - props, "\n" - ) -end +-- Generator.lua
+
+--[[
+Crafts an intermediate block palette format to be read by Cuberite.
+It processes the blocks.json report file (https://wiki.vg/Data_Generators)
+into a file that can be loaded into a BlockTypePalette (and is to be stored
+as Server/Protocol/<version>/base.btp.txt).
+
+The output format is the regular TSV BlockTypePalette, described in the
+$/src/BlockTypePalette.h file.
+--]]
+
+
+
+
+-- Allow Lua to load libraries in our subfolder:
+package.path = 'lib/lunajson/src/?.lua;' .. package.path;
+
+
+
+
+function spairs(t, order)
+ -- collect the keys
+ local keys = {}
+ for k in pairs(t) do keys[#keys+1] = k end
+
+ -- if order function given, sort by it by passing the table and keys a, b,
+ -- otherwise just sort the keys
+ if order then
+ table.sort(keys, function(a,b) return order(t, a, b) end)
+ else
+ table.sort(keys)
+ end
+
+ -- return the iterator function
+ local i = 0
+ return function()
+ i = i + 1
+ if keys[i] then
+ return keys[i], t[keys[i]]
+ end
+ end
+end
+
+
+
+--- Prints usage instructions to stdout.
+-- If the optional `aMessage` is passed, output is prepended by message _and_
+-- redirected to stderr.
+local function usage(aMessage)
+ if aMessage then
+ io.output(io.stderr);
+ io.write(aMessage, "\n\n");
+ end
+ io.write(
+ "Usage: lua Generator.lua INPUTFILE OUTPUTFILE\n"..
+ "Converts the Minecraft blocks.json report format to the cuberite "..
+ "block type palette format.\n"..
+ "\n"..
+ "INPUTFILE and OUTPUTFILE must point to a valid path. INPUTFILE must "..
+ "be readable and OUTPUTFILE must be writable. Either can be replaced "..
+ "with `-` (dash character) to point to standard-input or -output.\n");
+ os.exit(message and 1 or 0);
+end
+
+
+
+
+
+--- Parses the JSON registry into a Lua table
+--[[ The returned array-table has the following format:
+{
+ { id = 1, blockTypeName = "minecraft:stone", properties = {key = value, ...} },
+ ...
+}
+--]]
+local function parseRegistry(aBlockRegistryJsonStr)
+ assert(type(aBlockRegistryJsonStr) == "string")
+
+ local lj = require("lunajson")
+ local input = lj.decode(aBlockRegistryJsonStr)
+ local registry = {}
+ local idx = 1
+ for blockTypeName, blockData in pairs(input) do
+ local function tchelper(before, underscore, first)
+ return before..first:upper()
+ end
+
+ blockTypeName = blockTypeName:gsub("(%a)([_:])(%a)", tchelper)
+ print(blockTypeName)
+
+ for _, state in pairs(blockData.states) do
+ registry[idx] = {
+ id = state.id,
+ blockTypeName = blockTypeName,
+ properties = state.properties,
+ }
+ idx = idx + 1
+ end
+ end
+ return registry
+end
+
+
+
+
+
+--- Serializes the properties from the JSON / array table format into a single output string
+-- Concatenates all properties with \t as the delimiting character
+local function serializeProperties(aProperties)
+ local res = {}
+ local idx = 1
+ for k, v in pairs(aProperties or {}) do
+ res[idx] = k
+ res[idx + 1] = v
+ idx = idx + 2
+ end
+ return table.concat(res, "\t")
+end
+
+
+
+
+
+--- Returns the prefix that is common for all block type names in the registry
+-- aRegistry is the parsed registry, as returned from parseRegistry()
+local function findCommonPrefix(aRegistryTable)
+ local prefix = aRegistryTable[1].blockTypeName
+ local len = string.len(prefix)
+ local sub = string.sub
+ for _, block in ipairs(aRegistryTable) do
+ while (sub(block.blockTypeName, 1, len) ~= prefix) do
+ len = len - 1
+ if (len == 0) then
+ return ""
+ end
+ prefix = sub(prefix, 1, len)
+ end
+ end
+ return prefix
+end
+
+
+
+
+
+-- Test whether the script is run in a path where it can load it's libraries
+if not(pcall(function() require("lunajson") end)) then
+ usage(
+ "Could not load required libraries, please run `Generator.lua` " ..
+ "within its directory and make sure to run `git submodule update`."
+ )
+end
+
+-- Check/Prepare CLI arguments
+local inpath, outpath = ...;
+inpath = inpath or "blocks.json"
+outpath = outpath or "base.btp.txt"
+if (inpath ~= "-") then
+ local handle, err = io.open(inpath, "r")
+ io.input(handle or usage(err))
+end
+if (outpath ~= "-") then
+ local handle, err = io.open(outpath, "w")
+ io.output(handle or usage(err))
+end
+
+aBlockRegistryJsonStr = io.input():read("*a")
+assert(type(aBlockRegistryJsonStr) == "string")
+
+local function makeTitleCase(input)
+ local function tchelper(before, underscore, first)
+ return before..first:upper()
+ end
+
+ if (input == "hay_block") then
+ return "HayBale"
+ elseif (input == "tnt") then
+ return "TNT"
+ end
+
+ input = input:gsub("(%a)(_)(%a)", tchelper)
+ input = input:gsub("(%a)(_)(%a)", tchelper)
+ return (input:gsub("^%l", string.upper))
+end
+
+local input = require("lunajson").decode(aBlockRegistryJsonStr)
+local registry = {}
+header = true
+
+for blockTypeName, blockData in pairs(input) do
+
+ local default = 0
+ local properties = {}
+ local states = {}
+
+ blockTypeName = makeTitleCase(blockTypeName:gsub("minecraft:", "", 1))
+
+ if blockData.properties ~= nil then
+ for property, values in pairs(blockData.properties) do
+
+ local firstProperty = values[1]
+ local property = makeTitleCase(property)
+ local propertyType
+
+ if firstProperty == "true" then
+ propertyType = "bool"
+ elseif tonumber(firstProperty) ~= nil then
+ propertyType = "unsigned char"
+ elseif (firstProperty == "north") or (firstProperty == "down") then -- Down is special for Hopper
+ propertyType = "eBlockFace"
+ else
+ propertyType = {}
+ for _, value in pairs(values) do
+ table.insert(propertyType, makeTitleCase(value))
+ end
+ end
+
+ if property ~= "Waterlogged" then
+ properties[property] = propertyType
+ end
+ end
+ end
+
+ for _, state in pairs(blockData.states) do
+
+ local stateForThisId = {}
+ states[state.id] = stateForThisId
+
+ if state.default ~= nil then
+ default = state.id
+ end
+
+ if state.properties ~= nil then
+ for property, value in pairs(state.properties) do
+
+ local property = makeTitleCase(property)
+
+ if (property == "Waterlogged") then
+ if (value == "true") then
+ states[state.id] = nil
+ end
+ elseif type(properties[property]) == "table" then
+ stateForThisId[property] = property .. "::" .. makeTitleCase(value)
+ elseif (properties[property] == "eBlockFace") then
+ local faceMapping = {
+ ["north"] = "eBlockFace::BLOCK_FACE_ZM",
+ ["south"] = "eBlockFace::BLOCK_FACE_ZP",
+ ["west"] = "eBlockFace::BLOCK_FACE_XM",
+ ["east"] = "eBlockFace::BLOCK_FACE_XP",
+ ["up"] = "eBlockFace::BLOCK_FACE_YP",
+ ["down"] = "eBlockFace::BLOCK_FACE_YM"
+ }
+ stateForThisId[property] = faceMapping[value]
+ else
+ stateForThisId[property] = value
+ end
+ end
+ end
+ end
+
+ registry[blockTypeName] = { default, properties, states }
+end
+
+local function writeBlocksEnum(registry)
+ if not header then
+ return
+ end
+
+ local blockTypeNames = {}
+ for blockTypeName, _ in spairs(registry) do
+ table.insert(blockTypeNames, blockTypeName)
+ end
+ io.write(
+ "\nenum class Type\n{\n\t",
+ table.concat(blockTypeNames, ",\n\t"),
+ "\n};"
+ )
+end
+
+local function writeTypeGetter(registry)
+ io.write("\nenum Type Type(short ID)")
+
+ if header then
+ io.write(";")
+ return
+ end
+
+ io.write("\n{\n\tswitch(ID)\n\t{\n\t")
+
+ local lastBlockIndex = 0
+ for _, _ in pairs(registry) do
+ lastBlockIndex = lastBlockIndex + 1
+ end
+
+ local index = 0
+ local previousTypeName, _ = spairs(registry)()
+ for blockTypeName, blockData in spairs(registry) do
+ if (previousTypeName ~= blockTypeName) then
+ io.write(" return Type::", previousTypeName, ";\n\t")
+ previousTypeName = blockTypeName
+ end
+
+ index = index + 1
+ if (index == lastBlockIndex) then
+ io.write("default: return Type::", blockTypeName, ";\n\t}\n}")
+ return
+ end
+
+ for stateId, _ in spairs(blockData[3]) do
+ io.write("case ", stateId, ":")
+ end
+ end
+end
+
+local function writeTypeTester()
+ io.write("\nbool Is(short ID, enum Type Type)")
+ if header then
+ io.write(";")
+ else
+ io.write("\n{\n\treturn Block::Type(ID) == Type;\n}")
+ end
+end
+
+local function writeStateTypes(blockTypeName, properties)
+ if not header then
+ return
+ end
+
+ for property, propertyType in spairs(properties) do
+ if type(propertyType) == "table" then
+ io.write(
+ "\nenum class ", property, "\n{\n\t",
+ table.concat(propertyType, ",\n\t"),
+ "\n};"
+ )
+ end
+ end
+end
+
+local function writeDefaultSerialiser(blockTypeName, default)
+ io.write("\nshort ", blockTypeName, "()")
+ if header then
+ io.write(";")
+ else
+ io.write("\n{\n\treturn ", default, ";\n}")
+ end
+end
+
+local function adjustMaybeEnumType(property, propertyType)
+ if type(propertyType) == "table" then
+ return "enum " .. property
+ else
+ return propertyType
+ end
+end
+
+local function writeSerialisers(blockTypeName, properties, states)
+ if not header then
+ local argCount = 0
+ for property, _ in spairs(properties) do
+ argCount = argCount + 1
+ end
+ return argCount
+ end
+
+ local argCount = 0
+ local arguments = {}
+ for property, propertyType in spairs(properties) do
+ argCount = argCount + 1
+ local adjustedType = adjustMaybeEnumType(property, propertyType)
+ table.insert(arguments, adjustedType .. " " .. property)
+ end
+
+ io.write(
+ "\nconstexpr short ", blockTypeName,
+ "(", table.concat(arguments, ", "), ")\n{"
+ )
+
+ local lastStateIndex = 0
+ for _, _ in pairs(states) do
+ lastStateIndex = lastStateIndex + 1
+ end
+
+ local index = 0
+ for stateId, values in spairs(states) do
+ local equalities = {}
+ for property, value in spairs(values) do
+ if (value == "true") then
+ table.insert(equalities, property)
+ elseif (value == "false") then
+ table.insert(equalities, "!" .. property)
+ else
+ table.insert(equalities, property .. " == " .. value)
+ end
+ end
+
+ index = index + 1
+ if (index == lastStateIndex) then
+ io.write("\n\treturn ", stateId, ";\n}")
+ return argCount
+ else
+ io.write("\n\tif (", table.concat(equalities, " && "), ") return ", stateId, ";")
+ end
+ end
+end
+
+local function writeGetters(properties, states)
+ for property, propertyType in spairs(properties) do
+ local adjustedType = adjustMaybeEnumType(property, propertyType)
+ io.write("\n", adjustedType, " ", property, "(short ID)")
+
+ if header then
+ io.write(";")
+ else
+ io.write("\n{\n\tswitch(ID)\n\t{\n\t")
+
+ local valuesArray = {}
+ local lastValuesArrayIndex = 0
+
+ for stateId, propertyValuePairs in spairs(states) do
+ if (valuesArray[propertyValuePairs[property]] == nil) then
+ valuesArray[propertyValuePairs[property]] = {}
+ lastValuesArrayIndex = lastValuesArrayIndex + 1
+ end
+ table.insert(valuesArray[propertyValuePairs[property]], stateId)
+ end
+
+ local index = 0
+ local previousValue, _ = spairs(valuesArray)()
+ for value, stateIds in spairs(valuesArray) do
+ index = index + 1
+ if (index == lastValuesArrayIndex) then
+ io.write("default: return ", value, ";\n\t}\n}")
+ else
+ for _, stateId in spairs(stateIds) do
+ io.write("case ", stateId, ": ")
+ end
+ io.write("return ", value, ";\n\t")
+ end
+ end
+ end
+ end
+end
+
+local function writeBlocks(registry)
+ io.write("\nnamespace Block\n{")
+ writeBlocksEnum(registry)
+ writeTypeGetter(registry)
+ writeTypeTester()
+
+ for blockTypeName, blockData in spairs(registry) do
+ io.write("\nnamespace ", blockTypeName, "\n{")
+
+ local default = blockData[1]
+ local properties = blockData[2]
+ local states = blockData[3]
+
+ writeStateTypes(blockTypeName, properties)
+ if (writeSerialisers(blockTypeName, properties, states) > 0) then
+ writeDefaultSerialiser(blockTypeName, default)
+ end
+ writeGetters(properties, states)
+
+ io.write("\n}")
+ end
+ io.write("\n}")
+end
+
+local function writeGlobalPalette(registry)
+ io.write("UInt32 FromBlock(short ID)\n{\n\tusing namespace Block;\n\n\tswitch (ID)\n\t{")
+ for blockTypeName, blockData in spairs(registry) do
+ local states = blockData[3]
+ for stateId, propertyValuePairs in spairs(states) do
+ local values = {}
+ for property, value in spairs(propertyValuePairs) do
+ if (value == "true") or (value == "false") or (tonumber(value) ~= nil) or (string.sub(value,1,string.len("eBlockFace"))=="eBlockFace") then
+ table.insert(values, value)
+ else
+ table.insert(values, blockTypeName .. "::" .. value)
+ end
+ end
+ io.write(
+ "\n\tcase ", blockTypeName, "::", blockTypeName, "(", table.concat(values, ","),
+ "): return ", stateId, ";"
+ )
+ end
+ end
+ io.write("\n\tdefault: return 0;\n\t}\n}")
+end
+
+if false then
+ writeBlocks(registry)
+else
+ writeGlobalPalette(registry)
+end
diff --git a/Tools/BlockTypePaletteGenerator/ItemGenerator.lua b/Tools/BlockTypePaletteGenerator/ItemGenerator.lua new file mode 100644 index 000000000..5eff87603 --- /dev/null +++ b/Tools/BlockTypePaletteGenerator/ItemGenerator.lua @@ -0,0 +1,222 @@ +-- Generator.lua
+
+--[[
+Crafts an intermediate block palette format to be read by Cuberite.
+It processes the blocks.json report file (https://wiki.vg/Data_Generators)
+into a file that can be loaded into a BlockTypePalette (and is to be stored
+as Server/Protocol/<version>/base.btp.txt).
+
+The output format is the regular TSV BlockTypePalette, described in the
+$/src/BlockTypePalette.h file.
+--]]
+
+
+
+
+-- Allow Lua to load libraries in our subfolder:
+package.path = 'lib/lunajson/src/?.lua;' .. package.path;
+
+
+
+
+function spairs(t, order)
+ -- collect the keys
+ local keys = {}
+ for k in pairs(t) do keys[#keys+1] = k end
+
+ -- if order function given, sort by it by passing the table and keys a, b,
+ -- otherwise just sort the keys
+ if order then
+ table.sort(keys, function(a,b) return order(t, a, b) end)
+ else
+ table.sort(keys)
+ end
+
+ -- return the iterator function
+ local i = 0
+ return function()
+ i = i + 1
+ if keys[i] then
+ return keys[i], t[keys[i]]
+ end
+ end
+end
+
+
+
+--- Prints usage instructions to stdout.
+-- If the optional `aMessage` is passed, output is prepended by message _and_
+-- redirected to stderr.
+local function usage(aMessage)
+ if aMessage then
+ io.output(io.stderr);
+ io.write(aMessage, "\n\n");
+ end
+ io.write(
+ "Usage: lua Generator.lua INPUTFILE OUTPUTFILE\n"..
+ "Converts the Minecraft blocks.json report format to the cuberite "..
+ "block type palette format.\n"..
+ "\n"..
+ "INPUTFILE and OUTPUTFILE must point to a valid path. INPUTFILE must "..
+ "be readable and OUTPUTFILE must be writable. Either can be replaced "..
+ "with `-` (dash character) to point to standard-input or -output.\n");
+ os.exit(message and 1 or 0);
+end
+
+
+
+
+
+--- Parses the JSON registry into a Lua table
+--[[ The returned array-table has the following format:
+{
+ { id = 1, blockTypeName = "minecraft:stone", properties = {key = value, ...} },
+ ...
+}
+--]]
+local function parseRegistry(aBlockRegistryJsonStr)
+ assert(type(aBlockRegistryJsonStr) == "string")
+
+ local lj = require("lunajson")
+ local input = lj.decode(aBlockRegistryJsonStr)
+ local registry = {}
+ local idx = 1
+ for blockTypeName, blockData in pairs(input) do
+ local function tchelper(before, underscore, first)
+ return before..first:upper()
+ end
+
+ blockTypeName = blockTypeName:gsub("(%a)([_:])(%a)", tchelper)
+ print(blockTypeName)
+
+ for _, state in pairs(blockData.states) do
+ registry[idx] = {
+ id = state.id,
+ blockTypeName = blockTypeName,
+ properties = state.properties,
+ }
+ idx = idx + 1
+ end
+ end
+ return registry
+end
+
+
+
+
+
+--- Serializes the properties from the JSON / array table format into a single output string
+-- Concatenates all properties with \t as the delimiting character
+local function serializeProperties(aProperties)
+ local res = {}
+ local idx = 1
+ for k, v in pairs(aProperties or {}) do
+ res[idx] = k
+ res[idx + 1] = v
+ idx = idx + 2
+ end
+ return table.concat(res, "\t")
+end
+
+
+
+
+
+--- Returns the prefix that is common for all block type names in the registry
+-- aRegistry is the parsed registry, as returned from parseRegistry()
+local function findCommonPrefix(aRegistryTable)
+ local prefix = aRegistryTable[1].blockTypeName
+ local len = string.len(prefix)
+ local sub = string.sub
+ for _, block in ipairs(aRegistryTable) do
+ while (sub(block.blockTypeName, 1, len) ~= prefix) do
+ len = len - 1
+ if (len == 0) then
+ return ""
+ end
+ prefix = sub(prefix, 1, len)
+ end
+ end
+ return prefix
+end
+
+
+
+
+
+-- Test whether the script is run in a path where it can load it's libraries
+if not(pcall(function() require("lunajson") end)) then
+ usage(
+ "Could not load required libraries, please run `Generator.lua` " ..
+ "within its directory and make sure to run `git submodule update`."
+ )
+end
+
+-- Check/Prepare CLI arguments
+local inpath, outpath = ...;
+inpath = inpath or "blocks.json"
+outpath = outpath or "base.btp.txt"
+if (inpath ~= "-") then
+ local handle, err = io.open(inpath, "r")
+ io.input(handle or usage(err))
+end
+if (outpath ~= "-") then
+ local handle, err = io.open(outpath, "w")
+ io.output(handle or usage(err))
+end
+
+aBlockRegistryJsonStr = io.input():read("*a")
+assert(type(aBlockRegistryJsonStr) == "string")
+
+local function makeTitleCase(input)
+ local function tchelper(before, underscore, first)
+ return before..first:upper()
+ end
+
+ input = input:gsub("(%a)(_)(%a)", tchelper)
+ return (input:gsub("^%l", string.upper))
+end
+
+local input = require("lunajson").decode(aBlockRegistryJsonStr)
+local registry = {}
+header = true
+
+for itemName, id in spairs(input["minecraft:custom_stat"].entries) do
+ itemName = itemName:gsub("minecraft:", "", 1)
+ registry[itemName] = id.protocol_id
+end
+
+local function writeItems(registry)
+ io.write()
+
+ local names = {}
+ for itemName, _ in spairs(registry) do
+ table.insert(names, makeTitleCase(itemName))
+ end
+
+ io.write("\nenum class Statistic\n{\n", table.concat(names, ",\n"), "\n};")
+end
+
+local function writeGlobalPalette(registry)
+ io.write("UInt32 FromItem(Statistic ID)\n{\nswitch (ID)\n{")
+ for itemName, id in spairs(registry) do
+ io.write("\ncase Statistic::", makeTitleCase(itemName), ": return ", id, ";")
+ end
+ io.write("\ndefault: return 0;\n}\n}")
+end
+
+local function writeReverseGlobalPalette(registry)
+ io.write("Item ToStatistic(UInt32 ID)\n{\nswitch (ID)\n{")
+ for itemName, id in spairs(registry) do
+ io.write("\ncase ", id, ": return Item::", makeTitleCase(itemName), ";")
+ end
+ io.write("\ndefault: return Statistic::Air;\n}\n}")
+end
+
+if true then
+ writeItems(registry)
+else
+ writeGlobalPalette(registry)
+ io.write("\n\n")
+ writeReverseGlobalPalette(registry)
+end
diff --git a/Tools/BlockTypePaletteGenerator/convert.py b/Tools/BlockTypePaletteGenerator/convert.py new file mode 100644 index 000000000..1f1080271 --- /dev/null +++ b/Tools/BlockTypePaletteGenerator/convert.py @@ -0,0 +1,19 @@ +input = """"""
+
+def do(name, index, value):
+ trues = [name + "::East::Low", name + "::North::Low", name + "::South::Low", "true", name + "::West::Low"]
+ falses = [name + "::East::None", name + "::North::None", name + "::South::None", "false", name + "::West::None"]
+ if value == "true":
+ return trues[index]
+ return falses[index]
+
+for line in input.split("\n"):
+ if not "Wall(" in line:
+ print(line)
+ continue
+ line = line.strip()
+ start = line.find("(") + 1
+ end = line.find(")", start)
+ name = line.split("::")[0].split(" ")[1]
+ result = ",".join(do(name, index, value) for index, value in enumerate(line[start:end].split(",")))
+ print(line[0:start] + result + line[end:])
|