WIP: ore nodes, catching rules, bee nest fix, smaller Deep Dark
Done and checked: surface and cave-floor ore nodes (companion mod ore/OreNodes.kt), bigger and rarer underground veins; template with nodes passed the world check and the island quick check (node self-tests). Built, not yet tested: catching rules (catch rate falls with the level gap to the trainer's strongest Pokemon, failed catch enrages, strong wild Pokemon hunt weaker trainers; catching/, Fight or Flight config), bee nests emptied when their bee is turned away. In progress: the Deep Dark no longer fills the deepslate layer (split by temperature: cold = Deep Dark, hot = basalt deltas, warm = ordinary caves; world/biomes.json), zone layout regenerated; cave zone types added to world/zones.json but tools/zone_spawns.py doesn't use them yet; template not rebuilt for the new caves. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
362d06aa4b
commit
6361636da7
29 files changed
+1733
-357
No files matched your search
+24
-50
@@ -8,12 +8,11 @@
|
||||
0,0 (the island plus a strip of sea; the sea corners inside the square
|
||||
border generate when someone gets there).
|
||||
3. In the same session: load the circle again row by row until Regenerating
|
||||
Ore Veins has put veins into every chunk (it only fills a new chunk while
|
||||
it is loaded, 8 a tick, and Chunky is faster), place the showcase ore veins (world/zones.json →
|
||||
"ores", tiers with "showcase": one vein sticking out of the ground near
|
||||
its zone's sample point, so players see what a regenerating vein looks
|
||||
like), save, measure where the land ends (tools/world_report.py) and set
|
||||
a square world border `border_margin` blocks outside the outermost coast.
|
||||
Ore Veins has put its veins and the companion mod its ore nodes into every
|
||||
chunk (both only fill a new chunk while it is loaded, a few a tick, and
|
||||
Chunky is faster), save, measure where the land ends (tools/world_report.py)
|
||||
and set a square world border `border_margin` blocks outside the outermost
|
||||
coast.
|
||||
4. Copy the world to build/world-template without player data, then run
|
||||
the world checks and render the map (build/island-map.png).
|
||||
|
||||
@@ -36,14 +35,29 @@ from pathlib import Path
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
||||
from mcserver import BUILD, ROOT, SERVER, Server, chunky, eula_accepted, prepare, scan_log # noqa: E402
|
||||
import world_report # noqa: E402
|
||||
import zone_grid # noqa: E402
|
||||
from numpy import hypot as np_hypot # noqa: E402
|
||||
|
||||
TEMPLATE = BUILD / "world-template"
|
||||
SKIP = shutil.ignore_patterns("playerdata", "advancements", "stats", "session.lock")
|
||||
# A showcase sits this far from its zone's sample point (where guardians and the self-tests stand), first offset
|
||||
# that is still inside the zone wins.
|
||||
SHOWCASE_OFFSETS = [(16, 0), (0, 16), (-16, 0), (0, -16), (24, 24), (-24, -24)]
|
||||
|
||||
|
||||
def border_for(world, recipe):
|
||||
"""Square border around the land, `border_margin` past the outermost coast."""
|
||||
data = world_report.analyse(world)
|
||||
land = world_report.island_mask(data)
|
||||
zs, xs = land.nonzero()
|
||||
ox, oz = data["origin"]
|
||||
x0, x1 = int(xs.min()) + ox, int(xs.max()) + ox + 1
|
||||
z0, z1 = int(zs.min()) + oz, int(zs.max()) + oz + 1
|
||||
far = float(np_hypot(xs + ox, zs + oz).max())
|
||||
if far + recipe["border_margin"] > recipe["pregen_radius"]:
|
||||
sys.exit(f"land reaches {far:.0f} blocks from 0,0; raise pregen_radius ({recipe['pregen_radius']}) in "
|
||||
f"world/world.json to at least land + border_margin")
|
||||
cx, cz = round((x0 + x1) / 2), round((z0 + z1) / 2)
|
||||
size = max(x1 - x0, z1 - z0) + 2 * recipe["border_margin"]
|
||||
print(f"land spans x {x0}..{x1}, z {z0}..{z1}, at most {far:.0f} blocks from 0,0; "
|
||||
f"border center {cx},{cz} size {size}")
|
||||
return cx, cz, size
|
||||
|
||||
|
||||
def fill_veins(server, radius):
|
||||
@@ -72,45 +86,6 @@ def fill_veins(server, radius):
|
||||
return left
|
||||
|
||||
|
||||
def place_showcases(server):
|
||||
"""One hand-placed vein per showcase tier, half sunk into the ground near the zone's sample point."""
|
||||
plan = json.loads((ROOT / "world/zones.json").read_text())
|
||||
grid = zone_grid.load()
|
||||
samples = json.loads(zone_grid.ISLAND.read_text())["samples"]
|
||||
for tier, spec in plan["ores"].items():
|
||||
if not spec.get("showcase"):
|
||||
continue
|
||||
sx, _, sz = samples[spec["zone"]]
|
||||
spot = next(((sx + dx, sz + dz) for dx, dz in SHOWCASE_OFFSETS if grid.zone_at(sx + dx, sz + dz) == spec["zone"]), None)
|
||||
if spot is None:
|
||||
raise RuntimeError(f"no showcase spot inside {spec['zone']} near its sample point {sx},{sz}")
|
||||
x, z = spot
|
||||
server.command(f"forceload add {x} {z}")
|
||||
reply = server.command(f"execute in minecraft:overworld positioned {x} 0 {z} positioned over world_surface "
|
||||
f"positioned ~ ~-1 ~ run regenerating_ore_veins place {tier}_showcase").strip()
|
||||
server.command(f"forceload remove {x} {z}")
|
||||
print(f" showcase {tier} at {x},{z}: {reply[:100]}")
|
||||
|
||||
|
||||
def border_for(world, recipe):
|
||||
"""Square border around the land, `border_margin` past the outermost coast."""
|
||||
data = world_report.analyse(world)
|
||||
land = world_report.island_mask(data)
|
||||
zs, xs = land.nonzero()
|
||||
ox, oz = data["origin"]
|
||||
x0, x1 = int(xs.min()) + ox, int(xs.max()) + ox + 1
|
||||
z0, z1 = int(zs.min()) + oz, int(zs.max()) + oz + 1
|
||||
far = float(np_hypot(xs + ox, zs + oz).max())
|
||||
if far + recipe["border_margin"] > recipe["pregen_radius"]:
|
||||
sys.exit(f"land reaches {far:.0f} blocks from 0,0; raise pregen_radius ({recipe['pregen_radius']}) in "
|
||||
f"world/world.json to at least land + border_margin")
|
||||
cx, cz = round((x0 + x1) / 2), round((z0 + z1) / 2)
|
||||
size = max(x1 - x0, z1 - z0) + 2 * recipe["border_margin"]
|
||||
print(f"land spans x {x0}..{x1}, z {z0}..{z1}, at most {far:.0f} blocks from 0,0; "
|
||||
f"border center {cx},{cz} size {size}")
|
||||
return cx, cz, size
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
parser.parse_args()
|
||||
@@ -133,7 +108,6 @@ def main():
|
||||
seconds = server.pregenerate(0, 0, recipe["pregen_radius"], shape="circle")
|
||||
print(f"pregeneration finished in {seconds:.0f}s")
|
||||
fill_veins(server, recipe["pregen_radius"])
|
||||
place_showcases(server)
|
||||
server.command("save-all flush")
|
||||
cx, cz, size = border_for(world, recipe)
|
||||
print(f" {server.command(f'worldborder center {cx} {cz}').strip()}")
|
||||
|
||||
Reference in new issue
Block a user