Public Access
This commit is contained in:
1 parent
d9464fad76
commit
9ccec18c18
12 files changed
+153
-18
No files matched your search
@@ -495,6 +495,19 @@ accepts the existing authored distribution pages for those terrains. New Flat
|
|||||||
chunks can vary vegetation by biome; Void keeps biome climate without adding
|
chunks can vary vegetation by biome; Void keeps biome climate without adding
|
||||||
a floor or decorations. These are beta-port slices, not full 1.21.1 parity.
|
a floor or decorations. These are beta-port slices, not full 1.21.1 parity.
|
||||||
|
|
||||||
|
The local `1.0.1.37-beta.1` slice ports Cave terrain authoring using the
|
||||||
|
26.3 caves noise preset. Cave and Nether Biome pages can be distributed
|
||||||
|
through an Age, and travel searches for footing from Y=64 downward rather
|
||||||
|
than mistaking the cave roof for the surface. Nether-style cave material
|
||||||
|
replacement from 1.21.1 remains a separate port task. The local
|
||||||
|
`1.0.1.38-beta.1` follow-up
|
||||||
|
keeps Cave Ages dry by default: the vanilla 26.3 Cave preset otherwise fills
|
||||||
|
low openings with water. This changes newly generated chunks only; a future
|
||||||
|
Flooded page will deliberately set an authored water level in both maintained
|
||||||
|
versions.
|
||||||
|
The local `1.0.1.39-beta.1` follow-up makes the 26.3 landing search reject
|
||||||
|
fluid at feet and head height and prevents a submerged fallback platform.
|
||||||
|
|
||||||
## Verification of this first slice
|
## Verification of this first slice
|
||||||
|
|
||||||
The 1.21.1 `compileJava` and `build` tasks passed offline after the backend
|
The 1.21.1 `compileJava` and `build` tasks passed offline after the backend
|
||||||
|
|||||||
+18
-1
@@ -3,7 +3,7 @@
|
|||||||
This is an **experimental beta port** for issues #97–#104, not gameplay parity
|
This is an **experimental beta port** for issues #97–#104, not gameplay parity
|
||||||
with the Minecraft 1.21.1 release. The 26.3 backend persists separate Ages and
|
with the Minecraft 1.21.1 release. The 26.3 backend persists separate Ages and
|
||||||
their seeds. Books, the Book Binder, and the Ink Mixer work, and the Binder can
|
their seeds. Books, the Book Binder, and the Ink Mixer work, and the Binder can
|
||||||
author Standard, Amplified, Island, Flat, or Void terrain with supported
|
author Standard, Amplified, Island, Flat, Void, or Cave terrain with supported
|
||||||
biome-distribution pages. Other terrain families, feature/material effects,
|
biome-distribution pages. Other terrain families, feature/material effects,
|
||||||
portals, and much of
|
portals, and much of
|
||||||
the 1.21.1 gameplay remain unported. Use a test world and keep a backup; do not
|
the 1.21.1 gameplay remain unported. Use a test world and keep a backup; do not
|
||||||
@@ -177,6 +177,23 @@ surface decoration in Flat. Void continues to generate no floor or biome
|
|||||||
decoration. The operator-only `age create_multi` probe creates two-biome test
|
decoration. The operator-only `age create_multi` probe creates two-biome test
|
||||||
Ages for the dedicated-server smoke test.
|
Ages for the dedicated-server smoke test.
|
||||||
|
|
||||||
|
The local `1.0.1.37-beta.1` slice adds the Cave terrain page to Binder
|
||||||
|
authoring. It uses Minecraft's caves noise settings, accepts Cave and Nether
|
||||||
|
biome pages (including multi-biome distribution), and searches below Y=64 for
|
||||||
|
a safe arrival instead of landing on the roof. The 26.3 vanilla Cave preset
|
||||||
|
defaults to water below Y=32, so this port derives a dry Cave setting with
|
||||||
|
air as its default fluid and the sea level below the world floor. This applies
|
||||||
|
to newly generated Cave chunks; it does not drain existing chunks. Cave-specific Nether surface
|
||||||
|
materials from 1.21.1 are not ported yet. The dedicated-server smoke now
|
||||||
|
creates and reloads Cave Ages alongside the other terrain families.
|
||||||
|
|
||||||
|
The dry-Cave follow-up is packaged as `1.0.1.38-beta.1`; no 26.3 release is
|
||||||
|
published until the in-game check passes and publication is explicitly requested.
|
||||||
|
|
||||||
|
The local `1.0.1.39-beta.1` follow-up rejects fluid at both feet and head
|
||||||
|
height during safe-landing searches. It also refuses to carve the fallback
|
||||||
|
platform into submerged space if no dry footing can be found.
|
||||||
|
|
||||||
From the repository root:
|
From the repository root:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Rivencraft 26.3 beta 1.0.1.39-beta.1
|
||||||
|
|
||||||
|
This beta adds Cave terrain to authored Ages on Minecraft 26.3.
|
||||||
|
|
||||||
|
- Bind Descriptive Books with the Cave terrain page and Cave or Nether biome pages, including supported multi-biome distributions.
|
||||||
|
- Cave Ages use the cave noise shape but remain dry by default. Newly generated chunks no longer flood below the vanilla cave sea level.
|
||||||
|
- Cave travel searches from Y=64 downward for dry, properly footed space instead of landing on the cave roof or underwater.
|
||||||
|
- Expanded dedicated-server checks for Cave creation, biome distribution, and persistence after restart.
|
||||||
|
|
||||||
|
The player verified the Cave and safe-landing changes in game. Existing generated chunks are not drained or regenerated. A future Flooded page will provide an authored water level; see [issue #107](https://git.paddedcell.org/dnorberg/rivencraft/issues/107).
|
||||||
|
|
||||||
|
This 26.3 port is still experimental and does not yet include all features of the separate Minecraft 1.21.1 version. Use a test world and keep a backup. Minecraft 1.21.1 saves are not supported by this beta.
|
||||||
|
|
||||||
|
Requires Minecraft 26.3, NeoForge 26.3.0.99 or a compatible 26.3 build, and Java 25.
|
||||||
@@ -7,4 +7,4 @@ neo_version=26.3.0.99
|
|||||||
mod_id=rivencraft
|
mod_id=rivencraft
|
||||||
mod_name=Rivencraft
|
mod_name=Rivencraft
|
||||||
mod_license=LGPL-3.0-or-later
|
mod_license=LGPL-3.0-or-later
|
||||||
mod_version=1.0.1.36-beta.1
|
mod_version=1.0.1.39-beta.1
|
||||||
@@ -78,7 +78,7 @@ public final class PortAgeCommands {
|
|||||||
context, "terrain").toUpperCase(Locale.ROOT));
|
context, "terrain").toUpperCase(Locale.ROOT));
|
||||||
} catch (IllegalArgumentException exception) {
|
} catch (IllegalArgumentException exception) {
|
||||||
context.getSource().sendFailure(Component.literal(
|
context.getSource().sendFailure(Component.literal(
|
||||||
"Unknown terrain; use standard, amplified, island, flat, or void"));
|
"Unknown terrain; use standard, amplified, island, cave, flat, or void"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return createAge(context, terrain);
|
return createAge(context, terrain);
|
||||||
@@ -94,18 +94,23 @@ public final class PortAgeCommands {
|
|||||||
context, "terrain").toUpperCase(Locale.ROOT));
|
context, "terrain").toUpperCase(Locale.ROOT));
|
||||||
} catch (IllegalArgumentException exception) {
|
} catch (IllegalArgumentException exception) {
|
||||||
context.getSource().sendFailure(Component.literal(
|
context.getSource().sendFailure(Component.literal(
|
||||||
"Unknown terrain; use flat or void"));
|
"Unknown terrain; use cave, flat, or void"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (terrain != PortAgeTerrain.FLAT && terrain != PortAgeTerrain.VOID) {
|
if (terrain != PortAgeTerrain.CAVE
|
||||||
|
&& terrain != PortAgeTerrain.FLAT
|
||||||
|
&& terrain != PortAgeTerrain.VOID) {
|
||||||
context.getSource().sendFailure(Component.literal(
|
context.getSource().sendFailure(Component.literal(
|
||||||
"Multi-biome probe supports flat or void only"));
|
"Multi-biome probe supports cave, flat, or void only"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return createAge(context, terrain, new PortBiomePlan(
|
return createAge(context, terrain, new PortBiomePlan(
|
||||||
PortBiomePlan.Distribution.TILED, java.util.List.of(
|
PortBiomePlan.Distribution.TILED,
|
||||||
Identifier.withDefaultNamespace("plains"),
|
terrain == PortAgeTerrain.CAVE
|
||||||
Identifier.withDefaultNamespace("forest"))));
|
? java.util.List.of(Identifier.withDefaultNamespace("lush_caves"),
|
||||||
|
Identifier.withDefaultNamespace("dripstone_caves"))
|
||||||
|
: java.util.List.of(Identifier.withDefaultNamespace("plains"),
|
||||||
|
Identifier.withDefaultNamespace("forest"))));
|
||||||
})))))
|
})))))
|
||||||
.then(Commands.literal("list")
|
.then(Commands.literal("list")
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ public enum PortAgeTerrain {
|
|||||||
STANDARD,
|
STANDARD,
|
||||||
AMPLIFIED,
|
AMPLIFIED,
|
||||||
ISLAND,
|
ISLAND,
|
||||||
|
CAVE,
|
||||||
FLAT,
|
FLAT,
|
||||||
VOID
|
VOID
|
||||||
}
|
}
|
||||||
@@ -33,6 +33,27 @@ public final class PortAgeTravel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static BlockPos findLanding(ServerLevel target) {
|
private static BlockPos findLanding(ServerLevel target) {
|
||||||
|
if (target.getChunkSource().getGenerator() instanceof net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator noise
|
||||||
|
&& noise.generatorSettings().value().noiseSettings().equals(target.registryAccess()
|
||||||
|
.lookupOrThrow(Registries.NOISE_SETTINGS)
|
||||||
|
.getOrThrow(net.minecraft.world.level.levelgen.NoiseGeneratorSettings.CAVES)
|
||||||
|
.value().noiseSettings())) {
|
||||||
|
// The cave roof is not a valid arrival surface. Search down from
|
||||||
|
// Legacy's Y=64 start, then construct the normal safety platform
|
||||||
|
// at that height only when no footed opening can be found.
|
||||||
|
for (int radius = 0; radius <= 16; radius++) {
|
||||||
|
for (int x = -radius; x <= radius; x++) {
|
||||||
|
for (int z = -radius; z <= radius; z++) {
|
||||||
|
if (Math.max(Math.abs(x), Math.abs(z)) != radius) continue;
|
||||||
|
for (int y = Math.min(64, target.getMaxY() - 2); y > target.getMinY(); y--) {
|
||||||
|
BlockPos foot = new BlockPos(x, y, z);
|
||||||
|
if (hasFooting(target, foot)) return foot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return makePlatform(target, new BlockPos(0, 64, 0));
|
||||||
|
}
|
||||||
// A Flat Age has a known surface. Use it directly before a heightmap
|
// A Flat Age has a known surface. Use it directly before a heightmap
|
||||||
// fallback can place a platform in the air above a low superflat world.
|
// fallback can place a platform in the air above a low superflat world.
|
||||||
FlatLevelGeneratorSettings flatSettings = switch (target.getChunkSource().getGenerator()) {
|
FlatLevelGeneratorSettings flatSettings = switch (target.getChunkSource().getGenerator()) {
|
||||||
@@ -62,10 +83,21 @@ public final class PortAgeTravel {
|
|||||||
// origin is ocean or foliage. Final book landing rules are ported later.
|
// origin is ocean or foliage. Final book landing rules are ported later.
|
||||||
int y = Math.max(64, target.getHeight(Heightmap.Types.MOTION_BLOCKING, 0, 0) + 2);
|
int y = Math.max(64, target.getHeight(Heightmap.Types.MOTION_BLOCKING, 0, 0) + 2);
|
||||||
if (y + 2 >= target.getMaxY()) return null;
|
if (y + 2 >= target.getMaxY()) return null;
|
||||||
BlockPos foot = new BlockPos(0, y, 0);
|
return makePlatform(target, new BlockPos(0, y, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BlockPos makePlatform(ServerLevel target, BlockPos foot) {
|
||||||
|
if (foot.getY() <= target.getMinY() || foot.getY() + 2 >= target.getMaxY()) return null;
|
||||||
|
// A carved pocket inside a flooded cave immediately refills. Refuse
|
||||||
|
// that landing instead of placing the player in submerged spawn space.
|
||||||
|
if (!target.getFluidState(foot).isEmpty() || !target.getFluidState(foot.above()).isEmpty()) return null;
|
||||||
|
for (Direction direction : Direction.Plane.HORIZONTAL) {
|
||||||
|
if (!target.getFluidState(foot.relative(direction)).isEmpty()
|
||||||
|
|| !target.getFluidState(foot.above().relative(direction)).isEmpty()) return null;
|
||||||
|
}
|
||||||
for (int x = -1; x <= 1; x++) {
|
for (int x = -1; x <= 1; x++) {
|
||||||
for (int z = -1; z <= 1; z++) {
|
for (int z = -1; z <= 1; z++) {
|
||||||
target.setBlock(new BlockPos(x, y - 1, z), Rivencraft.CRYSTAL_BLOCK.get().defaultBlockState(), 3);
|
target.setBlock(foot.offset(x, -1, z), Rivencraft.CRYSTAL_BLOCK.get().defaultBlockState(), 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
target.setBlock(foot, Blocks.AIR.defaultBlockState(), 3);
|
target.setBlock(foot, Blocks.AIR.defaultBlockState(), 3);
|
||||||
@@ -76,6 +108,8 @@ public final class PortAgeTravel {
|
|||||||
private static boolean hasFooting(ServerLevel target, BlockPos foot) {
|
private static boolean hasFooting(ServerLevel target, BlockPos foot) {
|
||||||
BlockPos floor = foot.below();
|
BlockPos floor = foot.below();
|
||||||
return target.getBlockState(floor).isFaceSturdy(target, floor, Direction.UP)
|
return target.getBlockState(floor).isFaceSturdy(target, floor, Direction.UP)
|
||||||
|
&& target.getFluidState(foot).isEmpty()
|
||||||
|
&& target.getFluidState(foot.above()).isEmpty()
|
||||||
&& target.getBlockState(foot).getCollisionShape(target, foot).isEmpty()
|
&& target.getBlockState(foot).getCollisionShape(target, foot).isEmpty()
|
||||||
&& target.getBlockState(foot.above()).getCollisionShape(target, foot.above()).isEmpty();
|
&& target.getBlockState(foot.above()).getCollisionShape(target, foot.above()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import java.util.Map;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.OptionalLong;
|
import java.util.OptionalLong;
|
||||||
import net.dnorberg.rivencraft.Rivencraft;
|
import net.dnorberg.rivencraft.Rivencraft;
|
||||||
|
import net.dnorberg.rivencraft.writing.PortRegistryPages;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.HolderSet;
|
import net.minecraft.core.HolderSet;
|
||||||
@@ -325,7 +326,19 @@ public final class RuntimeAgeBackend {
|
|||||||
|| terrain != PortAgeTerrain.STANDARD) {
|
|| terrain != PortAgeTerrain.STANDARD) {
|
||||||
if (!(generator instanceof NoiseBasedChunkGenerator noise))
|
if (!(generator instanceof NoiseBasedChunkGenerator noise))
|
||||||
throw new IllegalStateException("Overworld generator cannot accept authored noise settings");
|
throw new IllegalStateException("Overworld generator cannot accept authored noise settings");
|
||||||
var source = generator.getBiomeSource();
|
var source = terrain == PortAgeTerrain.CAVE
|
||||||
|
? new FixedBiomeSource(server.registryAccess().lookupOrThrow(Registries.BIOME)
|
||||||
|
.getOrThrow(Biomes.LUSH_CAVES))
|
||||||
|
: generator.getBiomeSource();
|
||||||
|
if (terrain == PortAgeTerrain.CAVE && biomePlan != null) {
|
||||||
|
var biomes = server.registryAccess().lookupOrThrow(Registries.BIOME);
|
||||||
|
for (Identifier biomeId : biomePlan.biomes()) {
|
||||||
|
var holder = biomes.get(ResourceKey.create(Registries.BIOME, biomeId))
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException("Unknown authored biome: " + biomeId));
|
||||||
|
if (!PortRegistryPages.isCaveBiome(holder))
|
||||||
|
throw new IllegalArgumentException("Cave terrain requires a Cave or Nether biome: " + biomeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (biomePlan != null && biomePlan.distribution() != PortBiomePlan.Distribution.NATIVE) {
|
if (biomePlan != null && biomePlan.distribution() != PortBiomePlan.Distribution.NATIVE) {
|
||||||
source = authoredBiomeSource(server, biomePlan, seed);
|
source = authoredBiomeSource(server, biomePlan, seed);
|
||||||
}
|
}
|
||||||
@@ -335,6 +348,7 @@ public final class RuntimeAgeBackend {
|
|||||||
.getOrThrow(NoiseGeneratorSettings.AMPLIFIED);
|
.getOrThrow(NoiseGeneratorSettings.AMPLIFIED);
|
||||||
case ISLAND -> server.registryAccess().lookupOrThrow(Registries.NOISE_SETTINGS)
|
case ISLAND -> server.registryAccess().lookupOrThrow(Registries.NOISE_SETTINGS)
|
||||||
.getOrThrow(NoiseGeneratorSettings.FLOATING_ISLANDS);
|
.getOrThrow(NoiseGeneratorSettings.FLOATING_ISLANDS);
|
||||||
|
case CAVE -> dryCaveSettings(server);
|
||||||
case FLAT, VOID -> throw new IllegalStateException("Flat terrain should use FlatLevelSource");
|
case FLAT, VOID -> throw new IllegalStateException("Flat terrain should use FlatLevelSource");
|
||||||
};
|
};
|
||||||
generator = new NoiseBasedChunkGenerator(source, settings);
|
generator = new NoiseBasedChunkGenerator(source, settings);
|
||||||
@@ -369,4 +383,14 @@ public final class RuntimeAgeBackend {
|
|||||||
throw exception;
|
throw exception;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Holder<NoiseGeneratorSettings> dryCaveSettings(MinecraftServer server) {
|
||||||
|
NoiseGeneratorSettings caves = server.registryAccess().lookupOrThrow(Registries.NOISE_SETTINGS)
|
||||||
|
.getOrThrow(NoiseGeneratorSettings.CAVES).value();
|
||||||
|
return Holder.direct(new NoiseGeneratorSettings(
|
||||||
|
caves.noiseSettings(), caves.defaultBlock(), Blocks.AIR.defaultBlockState(),
|
||||||
|
caves.noiseRouter(), caves.materialRule(), caves.spawnTarget(),
|
||||||
|
caves.noiseSettings().minY() - 1, caves.disableMobGeneration(), Optional.empty(),
|
||||||
|
caves.useLegacyRandomSource(), caves.debugFunctions()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -23,6 +23,8 @@ public final class PortAuthoredWriting {
|
|||||||
Rivencraft.MOD_ID, "terrain/flat");
|
Rivencraft.MOD_ID, "terrain/flat");
|
||||||
private static final Identifier VOID_TERRAIN = Identifier.fromNamespaceAndPath(
|
private static final Identifier VOID_TERRAIN = Identifier.fromNamespaceAndPath(
|
||||||
Rivencraft.MOD_ID, "terrain/void");
|
Rivencraft.MOD_ID, "terrain/void");
|
||||||
|
private static final Identifier CAVE_TERRAIN = Identifier.fromNamespaceAndPath(
|
||||||
|
Rivencraft.MOD_ID, "terrain/cave");
|
||||||
|
|
||||||
private PortAuthoredWriting() {}
|
private PortAuthoredWriting() {}
|
||||||
|
|
||||||
@@ -60,7 +62,7 @@ public final class PortAuthoredWriting {
|
|||||||
private static boolean isTerrain(Identifier page) {
|
private static boolean isTerrain(Identifier page) {
|
||||||
return page.equals(STANDARD_TERRAIN) || page.equals(AMPLIFIED_TERRAIN)
|
return page.equals(STANDARD_TERRAIN) || page.equals(AMPLIFIED_TERRAIN)
|
||||||
|| page.equals(ISLAND_TERRAIN) || page.equals(FLAT_TERRAIN)
|
|| page.equals(ISLAND_TERRAIN) || page.equals(FLAT_TERRAIN)
|
||||||
|| page.equals(VOID_TERRAIN);
|
|| page.equals(VOID_TERRAIN) || page.equals(CAVE_TERRAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PortBiomePlan.Distribution controller(Identifier page) {
|
private static PortBiomePlan.Distribution controller(Identifier page) {
|
||||||
@@ -85,6 +87,7 @@ public final class PortAuthoredWriting {
|
|||||||
if (pages.contains(ISLAND_TERRAIN)) return PortAgeTerrain.ISLAND;
|
if (pages.contains(ISLAND_TERRAIN)) return PortAgeTerrain.ISLAND;
|
||||||
if (pages.contains(FLAT_TERRAIN)) return PortAgeTerrain.FLAT;
|
if (pages.contains(FLAT_TERRAIN)) return PortAgeTerrain.FLAT;
|
||||||
if (pages.contains(VOID_TERRAIN)) return PortAgeTerrain.VOID;
|
if (pages.contains(VOID_TERRAIN)) return PortAgeTerrain.VOID;
|
||||||
|
if (pages.contains(CAVE_TERRAIN)) return PortAgeTerrain.CAVE;
|
||||||
return PortAgeTerrain.STANDARD;
|
return PortAgeTerrain.STANDARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,14 +97,17 @@ public final class PortAuthoredWriting {
|
|||||||
"Unsupported terrain or biome-page combination in this port slice");
|
"Unsupported terrain or biome-page combination in this port slice");
|
||||||
List<Identifier> biomes = new ArrayList<>();
|
List<Identifier> biomes = new ArrayList<>();
|
||||||
PortBiomePlan.Distribution distribution = null;
|
PortBiomePlan.Distribution distribution = null;
|
||||||
|
boolean caveTerrain = pages.contains(CAVE_TERRAIN);
|
||||||
for (Identifier page : pages) {
|
for (Identifier page : pages) {
|
||||||
if (isTerrain(page)) continue;
|
if (isTerrain(page)) continue;
|
||||||
PortBiomePlan.Distribution selected = controller(page);
|
PortBiomePlan.Distribution selected = controller(page);
|
||||||
if (selected != null) { distribution = selected; continue; }
|
if (selected != null) { distribution = selected; continue; }
|
||||||
Identifier biome = PortRegistryPages.biomeId(page);
|
Identifier biome = PortRegistryPages.biomeId(page);
|
||||||
var registry = registries.lookupOrThrow(Registries.BIOME);
|
var registry = registries.lookupOrThrow(Registries.BIOME);
|
||||||
if (registry.get(ResourceKey.create(Registries.BIOME, biome)).isEmpty())
|
var holder = registry.get(ResourceKey.create(Registries.BIOME, biome))
|
||||||
throw new IllegalArgumentException("Unknown authored biome: " + biome);
|
.orElseThrow(() -> new IllegalArgumentException("Unknown authored biome: " + biome));
|
||||||
|
if (caveTerrain && !PortRegistryPages.isCaveBiome(holder))
|
||||||
|
throw new IllegalArgumentException("Cave terrain requires a Cave or Nether biome: " + biome);
|
||||||
biomes.add(biome);
|
biomes.add(biome);
|
||||||
}
|
}
|
||||||
if (distribution == PortBiomePlan.Distribution.NATIVE)
|
if (distribution == PortBiomePlan.Distribution.NATIVE)
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public final class PortRegistryPages {
|
|||||||
public static List<ItemStack> biomePages(HolderLookup.Provider registries, boolean caves) {
|
public static List<ItemStack> biomePages(HolderLookup.Provider registries, boolean caves) {
|
||||||
return registries.lookupOrThrow(Registries.BIOME).listElements()
|
return registries.lookupOrThrow(Registries.BIOME).listElements()
|
||||||
.filter(holder -> !holder.key().identifier().equals(DEFERRED_PLACEHOLDER))
|
.filter(holder -> !holder.key().identifier().equals(DEFERRED_PLACEHOLDER))
|
||||||
.filter(holder -> isCave(holder) == caves)
|
.filter(holder -> isCaveBiome(holder) == caves)
|
||||||
.map(holder -> PageItem.createSymbolPage(biomePageId(holder.key().identifier())))
|
.map(holder -> PageItem.createSymbolPage(biomePageId(holder.key().identifier())))
|
||||||
.sorted((left, right) -> left.get(Rivencraft.SYMBOL_PAGE_ID.get()).toString()
|
.sorted((left, right) -> left.get(Rivencraft.SYMBOL_PAGE_ID.get()).toString()
|
||||||
.compareTo(right.get(Rivencraft.SYMBOL_PAGE_ID.get()).toString()))
|
.compareTo(right.get(Rivencraft.SYMBOL_PAGE_ID.get()).toString()))
|
||||||
@@ -81,7 +81,7 @@ public final class PortRegistryPages {
|
|||||||
.map(id -> PageItem.createSymbolPage(blockPageId(id))).toList();
|
.map(id -> PageItem.createSymbolPage(blockPageId(id))).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isCave(net.minecraft.core.Holder.Reference<net.minecraft.world.level.biome.Biome> holder) {
|
public static boolean isCaveBiome(net.minecraft.core.Holder.Reference<net.minecraft.world.level.biome.Biome> holder) {
|
||||||
String path = holder.key().identifier().getPath();
|
String path = holder.key().identifier().getPath();
|
||||||
return holder.is(CAVE_BIOMES) || holder.is(BiomeTags.IS_NETHER)
|
return holder.is(CAVE_BIOMES) || holder.is(BiomeTags.IS_NETHER)
|
||||||
|| path.equals("deep_dark") || path.endsWith("_caves");
|
|| path.equals("deep_dark") || path.endsWith("_caves");
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"replace": false,
|
||||||
|
"values": [
|
||||||
|
"minecraft:lush_caves",
|
||||||
|
"minecraft:dripstone_caves",
|
||||||
|
"minecraft:deep_dark"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -71,8 +71,10 @@ send_and_wait 'rivencraft_port age create smoke_alpha 123456789' 'Created rivenc
|
|||||||
send_and_wait 'rivencraft_port age create smoke_beta 987654321' 'Created rivencraft:age/smoke_beta with seed 987654321'
|
send_and_wait 'rivencraft_port age create smoke_beta 987654321' 'Created rivencraft:age/smoke_beta with seed 987654321'
|
||||||
send_and_wait 'rivencraft_port age create smoke_flat 24680 flat' 'Created rivencraft:age/smoke_flat with seed 24680 terrain=FLAT'
|
send_and_wait 'rivencraft_port age create smoke_flat 24680 flat' 'Created rivencraft:age/smoke_flat with seed 24680 terrain=FLAT'
|
||||||
send_and_wait 'rivencraft_port age create smoke_void 13579 void' 'Created rivencraft:age/smoke_void with seed 13579 terrain=VOID'
|
send_and_wait 'rivencraft_port age create smoke_void 13579 void' 'Created rivencraft:age/smoke_void with seed 13579 terrain=VOID'
|
||||||
|
send_and_wait 'rivencraft_port age create smoke_cave 112233 cave' 'Created rivencraft:age/smoke_cave with seed 112233 terrain=CAVE'
|
||||||
send_and_wait 'rivencraft_port age create_multi smoke_flat_multi 24681 flat' 'Created rivencraft:age/smoke_flat_multi with seed 24681 terrain=FLAT'
|
send_and_wait 'rivencraft_port age create_multi smoke_flat_multi 24681 flat' 'Created rivencraft:age/smoke_flat_multi with seed 24681 terrain=FLAT'
|
||||||
send_and_wait 'rivencraft_port age create_multi smoke_void_multi 13580 void' 'Created rivencraft:age/smoke_void_multi with seed 13580 terrain=VOID'
|
send_and_wait 'rivencraft_port age create_multi smoke_void_multi 13580 void' 'Created rivencraft:age/smoke_void_multi with seed 13580 terrain=VOID'
|
||||||
|
send_and_wait 'rivencraft_port age create_multi smoke_cave_multi 112234 cave' 'Created rivencraft:age/smoke_cave_multi with seed 112234 terrain=CAVE'
|
||||||
# The index must reach disk while the server is still running. A graceful
|
# The index must reach disk while the server is still running. A graceful
|
||||||
# shutdown would hide the interrupted-save regression this checks.
|
# shutdown would hide the interrupted-save regression this checks.
|
||||||
index_file="$server_dir/world/dimensions/minecraft/overworld/data/rivencraft/runtime_ages.dat"
|
index_file="$server_dir/world/dimensions/minecraft/overworld/data/rivencraft/runtime_ages.dat"
|
||||||
@@ -84,18 +86,24 @@ gzip -dc "$index_file" | strings | grep -Fq 'rivencraft:age/smoke_alpha'
|
|||||||
gzip -dc "$index_file" | strings | grep -Fq 'rivencraft:age/smoke_beta'
|
gzip -dc "$index_file" | strings | grep -Fq 'rivencraft:age/smoke_beta'
|
||||||
gzip -dc "$index_file" | strings | grep -Fq 'rivencraft:age/smoke_flat'
|
gzip -dc "$index_file" | strings | grep -Fq 'rivencraft:age/smoke_flat'
|
||||||
gzip -dc "$index_file" | strings | grep -Fq 'rivencraft:age/smoke_void'
|
gzip -dc "$index_file" | strings | grep -Fq 'rivencraft:age/smoke_void'
|
||||||
|
gzip -dc "$index_file" | strings | grep -Fq 'rivencraft:age/smoke_cave'
|
||||||
gzip -dc "$index_file" | strings | grep -Fq 'rivencraft:age/smoke_flat_multi'
|
gzip -dc "$index_file" | strings | grep -Fq 'rivencraft:age/smoke_flat_multi'
|
||||||
gzip -dc "$index_file" | strings | grep -Fq 'rivencraft:age/smoke_void_multi'
|
gzip -dc "$index_file" | strings | grep -Fq 'rivencraft:age/smoke_void_multi'
|
||||||
|
gzip -dc "$index_file" | strings | grep -Fq 'rivencraft:age/smoke_cave_multi'
|
||||||
send_and_wait 'rivencraft_port age sample smoke_alpha' 'rivencraft:age/smoke_alpha seed=123456789 chunkOffset=0 terrain='
|
send_and_wait 'rivencraft_port age sample smoke_alpha' 'rivencraft:age/smoke_alpha seed=123456789 chunkOffset=0 terrain='
|
||||||
send_and_wait 'rivencraft_port age sample smoke_beta' 'rivencraft:age/smoke_beta seed=987654321 chunkOffset=0 terrain='
|
send_and_wait 'rivencraft_port age sample smoke_beta' 'rivencraft:age/smoke_beta seed=987654321 chunkOffset=0 terrain='
|
||||||
send_and_wait 'rivencraft_port age sample smoke_flat' 'rivencraft:age/smoke_flat seed=24680 chunkOffset=0 terrain='
|
send_and_wait 'rivencraft_port age sample smoke_flat' 'rivencraft:age/smoke_flat seed=24680 chunkOffset=0 terrain='
|
||||||
send_and_wait 'rivencraft_port age sample smoke_void' 'rivencraft:age/smoke_void seed=13579 chunkOffset=0 terrain='
|
send_and_wait 'rivencraft_port age sample smoke_void' 'rivencraft:age/smoke_void seed=13579 chunkOffset=0 terrain='
|
||||||
|
send_and_wait 'rivencraft_port age sample smoke_cave' 'rivencraft:age/smoke_cave seed=112233 chunkOffset=0 terrain='
|
||||||
send_and_wait 'rivencraft_port age sample smoke_flat_multi' 'rivencraft:age/smoke_flat_multi seed=24681 chunkOffset=0 terrain='
|
send_and_wait 'rivencraft_port age sample smoke_flat_multi' 'rivencraft:age/smoke_flat_multi seed=24681 chunkOffset=0 terrain='
|
||||||
send_and_wait 'rivencraft_port age sample smoke_void_multi' 'rivencraft:age/smoke_void_multi seed=13580 chunkOffset=0 terrain='
|
send_and_wait 'rivencraft_port age sample smoke_void_multi' 'rivencraft:age/smoke_void_multi seed=13580 chunkOffset=0 terrain='
|
||||||
|
send_and_wait 'rivencraft_port age sample smoke_cave_multi' 'rivencraft:age/smoke_cave_multi seed=112234 chunkOffset=0 terrain='
|
||||||
send_and_wait 'execute in rivencraft:age/smoke_flat run forceload add 0 0' 'Marked chunk [0, 0] in rivencraft:age/smoke_flat to be force loaded'
|
send_and_wait 'execute in rivencraft:age/smoke_flat run forceload add 0 0' 'Marked chunk [0, 0] in rivencraft:age/smoke_flat to be force loaded'
|
||||||
send_and_wait 'execute in rivencraft:age/smoke_void run forceload add 0 0' 'Marked chunk [0, 0] in rivencraft:age/smoke_void to be force loaded'
|
send_and_wait 'execute in rivencraft:age/smoke_void run forceload add 0 0' 'Marked chunk [0, 0] in rivencraft:age/smoke_void to be force loaded'
|
||||||
send_and_wait 'execute in rivencraft:age/smoke_flat_multi run forceload add 0 0' 'Marked chunk [0, 0] in rivencraft:age/smoke_flat_multi to be force loaded'
|
send_and_wait 'execute in rivencraft:age/smoke_flat_multi run forceload add 0 0' 'Marked chunk [0, 0] in rivencraft:age/smoke_flat_multi to be force loaded'
|
||||||
send_and_wait 'execute in rivencraft:age/smoke_void_multi run forceload add 0 0' 'Marked chunk [0, 0] in rivencraft:age/smoke_void_multi to be force loaded'
|
send_and_wait 'execute in rivencraft:age/smoke_void_multi run forceload add 0 0' 'Marked chunk [0, 0] in rivencraft:age/smoke_void_multi to be force loaded'
|
||||||
|
send_and_wait 'execute in rivencraft:age/smoke_cave run forceload add 0 0' 'Marked chunk [0, 0] in rivencraft:age/smoke_cave to be force loaded'
|
||||||
|
send_and_wait 'execute in rivencraft:age/smoke_cave_multi run forceload add 0 0' 'Marked chunk [0, 0] in rivencraft:age/smoke_cave_multi to be force loaded'
|
||||||
send_and_wait 'execute in rivencraft:age/smoke_flat if block 0 0 0 minecraft:bedrock run say Flat bedrock starts at Y0' 'Flat bedrock starts at Y0'
|
send_and_wait 'execute in rivencraft:age/smoke_flat if block 0 0 0 minecraft:bedrock run say Flat bedrock starts at Y0' 'Flat bedrock starts at Y0'
|
||||||
send_and_wait 'execute in rivencraft:age/smoke_flat if block 0 3 0 minecraft:grass_block run say Flat surface is Y3' 'Flat surface is Y3'
|
send_and_wait 'execute in rivencraft:age/smoke_flat if block 0 3 0 minecraft:grass_block run say Flat surface is Y3' 'Flat surface is Y3'
|
||||||
send_and_wait 'execute in rivencraft:age/smoke_void if block 0 0 0 minecraft:air run say Void remains empty' 'Void remains empty'
|
send_and_wait 'execute in rivencraft:age/smoke_void if block 0 0 0 minecraft:air run say Void remains empty' 'Void remains empty'
|
||||||
@@ -105,6 +113,8 @@ send_and_wait 'execute in rivencraft:age/smoke_void_multi if block 0 0 0 minecra
|
|||||||
send_and_wait 'rivencraft_port age biome smoke_flat_multi 128 128' 'rivencraft:age/smoke_flat_multi biome at 128,128=minecraft:plains'
|
send_and_wait 'rivencraft_port age biome smoke_flat_multi 128 128' 'rivencraft:age/smoke_flat_multi biome at 128,128=minecraft:plains'
|
||||||
send_and_wait 'rivencraft_port age biome smoke_flat_multi 384 128' 'rivencraft:age/smoke_flat_multi biome at 384,128=minecraft:forest'
|
send_and_wait 'rivencraft_port age biome smoke_flat_multi 384 128' 'rivencraft:age/smoke_flat_multi biome at 384,128=minecraft:forest'
|
||||||
send_and_wait 'rivencraft_port age biome smoke_void_multi 384 128' 'rivencraft:age/smoke_void_multi biome at 384,128=minecraft:forest'
|
send_and_wait 'rivencraft_port age biome smoke_void_multi 384 128' 'rivencraft:age/smoke_void_multi biome at 384,128=minecraft:forest'
|
||||||
|
send_and_wait 'rivencraft_port age biome smoke_cave_multi 128 128' 'rivencraft:age/smoke_cave_multi biome at 128,128=minecraft:lush_caves'
|
||||||
|
send_and_wait 'rivencraft_port age biome smoke_cave_multi 384 128' 'rivencraft:age/smoke_cave_multi biome at 384,128=minecraft:dripstone_caves'
|
||||||
alpha_before=$(grep -F 'rivencraft:age/smoke_alpha seed=123456789 chunkOffset=0 terrain=' "$log_file" | tail -1 | sed 's/.*terrain=//')
|
alpha_before=$(grep -F 'rivencraft:age/smoke_alpha seed=123456789 chunkOffset=0 terrain=' "$log_file" | tail -1 | sed 's/.*terrain=//')
|
||||||
beta_before=$(grep -F 'rivencraft:age/smoke_beta seed=987654321 chunkOffset=0 terrain=' "$log_file" | tail -1 | sed 's/.*terrain=//')
|
beta_before=$(grep -F 'rivencraft:age/smoke_beta seed=987654321 chunkOffset=0 terrain=' "$log_file" | tail -1 | sed 's/.*terrain=//')
|
||||||
flat_before=$(grep -F 'rivencraft:age/smoke_flat seed=24680 chunkOffset=0 terrain=' "$log_file" | tail -1 | sed 's/.*terrain=//')
|
flat_before=$(grep -F 'rivencraft:age/smoke_flat seed=24680 chunkOffset=0 terrain=' "$log_file" | tail -1 | sed 's/.*terrain=//')
|
||||||
@@ -125,10 +135,13 @@ send_and_wait 'rivencraft_port age sample smoke_alpha' 'rivencraft:age/smoke_alp
|
|||||||
send_and_wait 'rivencraft_port age sample smoke_beta' 'rivencraft:age/smoke_beta seed=987654321 chunkOffset=0 terrain='
|
send_and_wait 'rivencraft_port age sample smoke_beta' 'rivencraft:age/smoke_beta seed=987654321 chunkOffset=0 terrain='
|
||||||
send_and_wait 'rivencraft_port age sample smoke_flat' 'rivencraft:age/smoke_flat seed=24680 chunkOffset=0 terrain='
|
send_and_wait 'rivencraft_port age sample smoke_flat' 'rivencraft:age/smoke_flat seed=24680 chunkOffset=0 terrain='
|
||||||
send_and_wait 'rivencraft_port age sample smoke_void' 'rivencraft:age/smoke_void seed=13579 chunkOffset=0 terrain='
|
send_and_wait 'rivencraft_port age sample smoke_void' 'rivencraft:age/smoke_void seed=13579 chunkOffset=0 terrain='
|
||||||
|
send_and_wait 'rivencraft_port age sample smoke_cave' 'rivencraft:age/smoke_cave seed=112233 chunkOffset=0 terrain='
|
||||||
send_and_wait 'rivencraft_port age sample smoke_flat_multi' 'rivencraft:age/smoke_flat_multi seed=24681 chunkOffset=0 terrain='
|
send_and_wait 'rivencraft_port age sample smoke_flat_multi' 'rivencraft:age/smoke_flat_multi seed=24681 chunkOffset=0 terrain='
|
||||||
send_and_wait 'rivencraft_port age sample smoke_void_multi' 'rivencraft:age/smoke_void_multi seed=13580 chunkOffset=0 terrain='
|
send_and_wait 'rivencraft_port age sample smoke_void_multi' 'rivencraft:age/smoke_void_multi seed=13580 chunkOffset=0 terrain='
|
||||||
|
send_and_wait 'rivencraft_port age sample smoke_cave_multi' 'rivencraft:age/smoke_cave_multi seed=112234 chunkOffset=0 terrain='
|
||||||
send_and_wait 'rivencraft_port age biome smoke_flat_multi 384 128' 'rivencraft:age/smoke_flat_multi biome at 384,128=minecraft:forest'
|
send_and_wait 'rivencraft_port age biome smoke_flat_multi 384 128' 'rivencraft:age/smoke_flat_multi biome at 384,128=minecraft:forest'
|
||||||
send_and_wait 'rivencraft_port age biome smoke_void_multi 384 128' 'rivencraft:age/smoke_void_multi biome at 384,128=minecraft:forest'
|
send_and_wait 'rivencraft_port age biome smoke_void_multi 384 128' 'rivencraft:age/smoke_void_multi biome at 384,128=minecraft:forest'
|
||||||
|
send_and_wait 'rivencraft_port age biome smoke_cave_multi 384 128' 'rivencraft:age/smoke_cave_multi biome at 384,128=minecraft:dripstone_caves'
|
||||||
alpha_after=$(grep -F 'rivencraft:age/smoke_alpha seed=123456789 chunkOffset=0 terrain=' "$log_file" | tail -1 | sed 's/.*terrain=//')
|
alpha_after=$(grep -F 'rivencraft:age/smoke_alpha seed=123456789 chunkOffset=0 terrain=' "$log_file" | tail -1 | sed 's/.*terrain=//')
|
||||||
beta_after=$(grep -F 'rivencraft:age/smoke_beta seed=987654321 chunkOffset=0 terrain=' "$log_file" | tail -1 | sed 's/.*terrain=//')
|
beta_after=$(grep -F 'rivencraft:age/smoke_beta seed=987654321 chunkOffset=0 terrain=' "$log_file" | tail -1 | sed 's/.*terrain=//')
|
||||||
flat_after=$(grep -F 'rivencraft:age/smoke_flat seed=24680 chunkOffset=0 terrain=' "$log_file" | tail -1 | sed 's/.*terrain=//')
|
flat_after=$(grep -F 'rivencraft:age/smoke_flat seed=24680 chunkOffset=0 terrain=' "$log_file" | tail -1 | sed 's/.*terrain=//')
|
||||||
@@ -144,4 +157,4 @@ void_after=$(grep -F 'rivencraft:age/smoke_void seed=13579 chunkOffset=0 terrain
|
|||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
stop_server
|
stop_server
|
||||||
printf '26.3 dedicated-server smoke passed: Standard, Flat and Void Ages persisted across restart.\n'
|
printf '26.3 dedicated-server smoke passed: Standard, Flat, Void and Cave Ages persisted across restart.\n'
|
||||||
Reference in new issue
Block a user