Skip to content

Instantly share code, notes, and snippets.

@uint0
Last active February 21, 2021 02:32
Show Gist options
  • Save uint0/a546cb2c99e28a2e50b646e8743dbeeb to your computer and use it in GitHub Desktop.
Save uint0/a546cb2c99e28a2e50b646e8743dbeeb to your computer and use it in GitHub Desktop.
A script for generating resource lists for create schematics
from nbt import nbt
import typing
import collections
class ResourceListContainer(typing.TypedDict):
block: typing.List[collections.Counter]
entity: typing.List[collections.Counter]
def read_nbt_file(file_path: str) -> nbt.NBTFile:
nbtfile = nbt.NBTFile(file_path, 'rb')
return nbtfile
def get_block_resources(nbtfile: nbt.NBTFile, palette: typing.List[str]) -> collections.Counter:
counter = collections.Counter()
for block_def in nbtfile['blocks']:
state = block_def['state'].value
block = palette[state]
counter[block] += 1
return counter
def get_entity_resources(nbtfile: nbt.NBTFile) -> collections.Counter:
counter = collections.Counter()
for entity_def in nbtfile['entities']:
entity_nbt = entity_def['nbt']
entity_name = entity_nbt['id'].value
counter[entity_name] += 1
# TODO: factor this into another method
if entity_name == "minecraft:item_frame":
counter[entity_nbt['Item']['id'].value] += 1
return counter
def get_block_palette(nbtfile: nbt.NBTFile) -> typing.List[str]:
return [
entry['Name'].value for entry in nbtfile['palette']
]
def get_resource_list(schematic_name: str) -> ResourceListContainer:
nbtfile = read_nbt_file(schematic_name)
block_palette = get_block_palette(nbtfile)
block_resources = get_block_resources(nbtfile, block_palette)
entity_resources = get_entity_resources(nbtfile)
return {
'block': block_resources,
'entity': entity_resources
}
def print_resource_type_list(resource_type_list: collections.Counter, indent: int = 2) -> None:
if len(resource_type_list) == 0:
print(' '*indent, 'No Resources')
return
common_sorted = resource_type_list.most_common(len(resource_type_list))
max_str_len = max(len(s) for s,_ in common_sorted)
# Get hacked 101
fmt_str = " "*indent + f"{{name:<{max_str_len}}}\t{{count}}"
for name, count in common_sorted:
info_line = [fmt_str.format(name=name, count=count)]
if count > 64:
info_line.append(f" = {count//64}s + {count%64}i")
print("\t".join(info_line))
if __name__ == '__main__':
import sys
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} <Path to schematic>", file=sys.stderr)
sys.exit(1)
resource_list = get_resource_list(sys.argv[1])
print('Blocks:')
print_resource_type_list(resource_list['block'])
print('Entities:')
print_resource_type_list(resource_list['entity'])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment