Skip to content

Instantly share code, notes, and snippets.

@J0B10
Last active February 2, 2022 21:24
Show Gist options
  • Save J0B10/d95d51372d0e129690b795e8104daa81 to your computer and use it in GitHub Desktop.
Save J0B10/d95d51372d0e129690b795e8104daa81 to your computer and use it in GitHub Desktop.
MCEdit Filter for generating a Just Enough Resources compatible worldgen.json

JER export filter

This is a filter for Podshot/MCEdit-Unified.

It analyzes the selected region and creates a worldgen.json that contains the distribution of all blocks.
This file can then be read by Just Enough Resources (make sure to set diyData=true in the config).
It will display all the data in a butifull gui ingame.

For improved performance compile the python script:

py -2 -m py_compile jer_export.py

Drop it in mcedit/stock-filters.

Arguments

  • Worldgen File - file where worldgen.json should be saved
  • Keep Drops- if drops from an already existing worldgen.json should be preserved
  • Threshold - minimum fraction of blocks that has to be found to show up (0.01 is 1%)
#! python version 2.7
import os
import json
import re
# The MCEdit 1.0 filter name
displayName = "JER export"
# filter settings
inputs = (
# file where worldgen.json should be saved
("Worldgen File", ("file-save", ["*.json"])),
# if drops from an already existing worldgen.json should be preserved
("Keep Drops", True),
# minimum fraction of blocks that has to be found to show up
("Threshold", 0.0001),
# txt file containing a blacklist of blocks that should be ignored
("Resource Blacklist", "file-open"),
# tick if the txt file should be a whitelist instead
("is Whitelist", False),
)
# dict for mapping from numeric blockids to strings
blockids = {}
# list containing all blacklisted blocks
blacklist = []
# converts the block with the given numeric id and meta to a blockstring
def toBlockString(id, meta):
return blockids[id] + ":" + str(meta);
# retrieves the blockstring in the given level at the specified coordinates
def blockAt(level, x, y, z):
return toBlockString(level.blockAt(x, y, z), level.blockDataAt(x, y, z));
def isBlacklisted(block, isWhitelist):
for s in blacklist:
if block.startswith(s):
return not isWhitelist
return isWhitelist
# run the filter
def perform(level, box, options):
# read moedded blockids from level.dat
print("Reading blockids from level.dat...")
for comp in level.root_tag["FML"]["Registries"]["minecraft:blocks"]["ids"]:
key = comp["K"].value
value = comp["V"].value
blockids[value] = key
print(str(len(blockids)) + " blocks found!")
#Worldgen file
file = options["Worldgen File"]
# dictionary containing all drops, key is block id, value is a dict
drops = {}
#dictionary containing all blocks found at certain levels
results = {}
# load old drops if desired
if options["Keep Drops"]:
if file == None:
raise Exception("Worldgen File not specified")
if os.path.exists(file):
print("Loading old drops")
with open(file) as f:
wg = json.load(f)
for entry in wg:
block = entry["block"]
if "dropsList" in entry:
val = {
"silktouch": entry["silktouch"],
"dropsList": entry["dropsList"]
}
else:
val = {
"silktouch": entry["silktouch"] if "silktouch" in entry else False,
}
drops[block] = val
else:
print("Worldgen File does not exist so drops couldn't be kept")
#load blacklist
blcklstFile = options["Resource Blacklist"]
if blcklstFile != None:
if not os.path.exists(blcklstFile):
raise Exception("File does not exist: " + blcklstFile)
with open(blcklstFile) as f:
#FIXME for some strange reason blacklist does not work properly
# let's ignore this for now as blacklist is not really needed
blacklist = f.readlines()
# count occurrences of blocks, layer by layer
print("Profiling blocks:")
totalblocks = 0.0
for y in xrange(box.miny, box.maxy):
print(" y=" + str(y) + " (" + str(round((y-box.miny) * 100 / (box.maxy-box.miny), 1)) + "%)")
layerblocks = 0.0
for x in xrange(box.minx, box.maxx):
for z in xrange(box.minz, box.maxz):
block = blockAt(level, x, y, z)
if block != "minecraft:air:0":
if isBlacklisted(block, options["is Whitelist"]):
#skip blacklisted blocks
continue
layerblocks += 1.0
if block not in results:
results[block] = {}
if y in results[block]:
results[block][y] += 1.0;
else:
results[block][y] = 1.0;
totalblocks = layerblocks if layerblocks > totalblocks else totalblocks
print("Done!")
# generate the output dict
print("Generating JSON")
out = []
for block, spread in results.iteritems():
distribution = ""
prev = float("nan")
prevY = -1
for y in xrange(box.miny, box.maxy):
count = spread[y] if y in spread else 0.0
val = count / totalblocks
val = val if val >= options["Threshold"] else 0.0;
if prev != val:
if prevY != y - 1:
distribution += str(y - 1) + "," + str(prev) + ";"
distribution += str(y) + "," + str(val) + ";"
prev = val
prevY = y
if block in drops:
if "dropsList" in drops[block]:
entry = {
"block": block,
"distrib": distribution,
"silktouch": drops[block]["silktouch"],
"dropsList": drops[block]["dropsList"],
"dim": "Dim 0: overworld",
}
else:
entry = {
"block": block,
"distrib": distribution,
"silktouch": drops[block]["silktouch"],
"dim": "Dim 0: overworld",
}
else:
entry = {
"block": block,
"distrib": distribution,
"silktouch": False,
"dim": "Dim 0: overworld",
}
out.append(entry)
print("Writing JSON to " + file)
with open(file, 'w') as fp:
json.dump(out, fp, indent = 4, sort_keys = True)
print("Complete!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment