Public Access
This commit is contained in:
1 parent
6c1c90b171
commit
3ad518232a
5 files changed
+64
-22
No files matched your search
@@ -323,6 +323,12 @@ Overworld-like surfaces together with the persisted Native or Single biome
|
|||||||
distribution. This prevents Nether terrain generation from leaking into newly
|
distribution. This prevents Nether terrain generation from leaking into newly
|
||||||
generated Cave Age chunks.
|
generated Cave Age chunks.
|
||||||
|
|
||||||
|
Version 0.2.22.0 applies Tiled Biome Distribution using two deterministic
|
||||||
|
Age-seeded biomes in the legacy diagonal-checkerboard layout. Each square is
|
||||||
|
16 chunks (256 blocks) wide, matching Mystcraft Legacy's coordinate shift, and
|
||||||
|
uses Minecraft's serializable checkerboard biome source so the layout remains
|
||||||
|
stable across server reloads.
|
||||||
|
|
||||||
Version 0.2.14.0 restores the legacy Linking and Descriptive Book artwork for
|
Version 0.2.14.0 restores the legacy Linking and Descriptive Book artwork for
|
||||||
inventory items and gives each book its matching open-book texture when placed
|
inventory items and gives each book its matching open-book texture when placed
|
||||||
on a Book Stand. Return Linking Books created inside another Age also retain and
|
on a Book Stand. Return Linking Books created inside another Age also retain and
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ mod_name=Rivencraft
|
|||||||
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
||||||
mod_license=LGPL-3.0-or-later
|
mod_license=LGPL-3.0-or-later
|
||||||
# The mod version. Rivencraft uses the x.y.z.b policy documented in README.md.
|
# The mod version. Rivencraft uses the x.y.z.b policy documented in README.md.
|
||||||
mod_version=0.2.21.1
|
mod_version=0.2.22.0
|
||||||
immersive_portals_version=6.0.7
|
immersive_portals_version=6.0.7
|
||||||
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
|
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
|
||||||
# This should match the base package used for the mod sources.
|
# This should match the base package used for the mod sources.
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public record AgeDefinition(
|
|||||||
public static final ResourceLocation RANDOM_VANILLA_PROFILE = ResourceLocation.fromNamespaceAndPath(
|
public static final ResourceLocation RANDOM_VANILLA_PROFILE = ResourceLocation.fromNamespaceAndPath(
|
||||||
Rivencraft.MOD_ID, "random_vanilla"
|
Rivencraft.MOD_ID, "random_vanilla"
|
||||||
);
|
);
|
||||||
public static final int CURRENT_GENERATION_VERSION = 9;
|
public static final int CURRENT_GENERATION_VERSION = 10;
|
||||||
|
|
||||||
public AgeDefinition {
|
public AgeDefinition {
|
||||||
Objects.requireNonNull(id, "id");
|
Objects.requireNonNull(id, "id");
|
||||||
|
|||||||
@@ -6,10 +6,12 @@ import java.util.Optional;
|
|||||||
import java.util.OptionalLong;
|
import java.util.OptionalLong;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.Collections;
|
||||||
import net.dnorberg.rivencraft.Rivencraft;
|
import net.dnorberg.rivencraft.Rivencraft;
|
||||||
import net.dnorberg.rivencraft.compat.ImmersivePortalsChunkLoaders;
|
import net.dnorberg.rivencraft.compat.ImmersivePortalsChunkLoaders;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.GlobalPos;
|
import net.minecraft.core.GlobalPos;
|
||||||
|
import net.minecraft.core.HolderSet;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
@@ -23,6 +25,7 @@ import net.minecraft.world.level.block.Blocks;
|
|||||||
import net.minecraft.world.level.biome.Biomes;
|
import net.minecraft.world.level.biome.Biomes;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
import net.minecraft.world.level.biome.BiomeSource;
|
import net.minecraft.world.level.biome.BiomeSource;
|
||||||
|
import net.minecraft.world.level.biome.CheckerboardColumnBiomeSource;
|
||||||
import net.minecraft.world.level.biome.FixedBiomeSource;
|
import net.minecraft.world.level.biome.FixedBiomeSource;
|
||||||
import net.minecraft.world.level.biome.MultiNoiseBiomeSource;
|
import net.minecraft.world.level.biome.MultiNoiseBiomeSource;
|
||||||
import net.minecraft.world.level.biome.MultiNoiseBiomeSourceParameterLists;
|
import net.minecraft.world.level.biome.MultiNoiseBiomeSourceParameterLists;
|
||||||
@@ -42,6 +45,7 @@ public final class AgeDimensionService {
|
|||||||
private static final int SURFACE_SEARCH_RADIUS = 16;
|
private static final int SURFACE_SEARCH_RADIUS = 16;
|
||||||
private static final int FALLBACK_PLATFORM_Y = 63;
|
private static final int FALLBACK_PLATFORM_Y = 63;
|
||||||
private static final int CAVE_SPAWN_SEARCH_Y = 64;
|
private static final int CAVE_SPAWN_SEARCH_Y = 64;
|
||||||
|
private static final int TILED_BIOME_SCALE = 4;
|
||||||
|
|
||||||
private AgeDimensionService() {
|
private AgeDimensionService() {
|
||||||
}
|
}
|
||||||
@@ -278,16 +282,22 @@ public final class AgeDimensionService {
|
|||||||
AgeDefinition age,
|
AgeDefinition age,
|
||||||
net.minecraft.core.HolderGetter<net.minecraft.world.level.biome.MultiNoiseBiomeSourceParameterList> biomeParameters
|
net.minecraft.core.HolderGetter<net.minecraft.world.level.biome.MultiNoiseBiomeSourceParameterList> biomeParameters
|
||||||
) {
|
) {
|
||||||
if (age.traits().biomeDistribution() == AgeTraits.BiomeDistribution.SINGLE) {
|
List<net.minecraft.core.Holder.Reference<Biome>> biomes = server.registryAccess()
|
||||||
List<net.minecraft.core.Holder.Reference<Biome>> biomes = server.registryAccess()
|
.lookupOrThrow(Registries.BIOME)
|
||||||
.lookupOrThrow(Registries.BIOME)
|
.listElements()
|
||||||
.listElements()
|
.sorted(Comparator.comparing(holder -> holder.key().location().toString()))
|
||||||
.sorted(Comparator.comparing(holder -> holder.key().location().toString()))
|
.toList();
|
||||||
.toList();
|
if (age.traits().biomeDistribution() == AgeTraits.BiomeDistribution.SINGLE && !biomes.isEmpty()) {
|
||||||
if (!biomes.isEmpty()) {
|
int index = Math.floorMod(Long.hashCode(age.seed() ^ 0x53494E474C454249L), biomes.size());
|
||||||
int index = Math.floorMod(Long.hashCode(age.seed() ^ 0x53494E474C454249L), biomes.size());
|
return new FixedBiomeSource(biomes.get(index));
|
||||||
return new FixedBiomeSource(biomes.get(index));
|
}
|
||||||
}
|
if (age.traits().biomeDistribution() == AgeTraits.BiomeDistribution.TILED && biomes.size() >= 2) {
|
||||||
|
List<net.minecraft.core.Holder.Reference<Biome>> selected = new java.util.ArrayList<>(biomes);
|
||||||
|
Collections.shuffle(selected, new java.util.Random(age.seed() ^ 0x54494C454442494FL));
|
||||||
|
return new CheckerboardColumnBiomeSource(
|
||||||
|
HolderSet.direct(List.of(selected.get(0), selected.get(1))),
|
||||||
|
TILED_BIOME_SCALE
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return MultiNoiseBiomeSource.createFromPreset(
|
return MultiNoiseBiomeSource.createFromPreset(
|
||||||
biomeParameters.getOrThrow(MultiNoiseBiomeSourceParameterLists.OVERWORLD));
|
biomeParameters.getOrThrow(MultiNoiseBiomeSourceParameterLists.OVERWORLD));
|
||||||
|
|||||||
@@ -155,6 +155,26 @@ public final class LinkingGameTests {
|
|||||||
public static void legacyBaseTerrainProfilesLoadRuntimeDimensions(GameTestHelper helper) {
|
public static void legacyBaseTerrainProfilesLoadRuntimeDimensions(GameTestHelper helper) {
|
||||||
for (var profile : AgeGenerationProfiles.all()) {
|
for (var profile : AgeGenerationProfiles.all()) {
|
||||||
UUID id = UUID.randomUUID();
|
UUID id = UUID.randomUUID();
|
||||||
|
AgeTraits selectedTraits = AgeTraits.select(id.getMostSignificantBits());
|
||||||
|
AgeTraits traits = profile.equals(AgeGenerationProfiles.STANDARD)
|
||||||
|
? new AgeTraits(
|
||||||
|
AgeTraits.BiomeDistribution.SINGLE,
|
||||||
|
AgeTraits.Lighting.NORMAL,
|
||||||
|
AgeTraits.Weather.NORMAL,
|
||||||
|
1.0D,
|
||||||
|
0.0F,
|
||||||
|
0.0F
|
||||||
|
)
|
||||||
|
: profile.equals(AgeGenerationProfiles.AMPLIFIED)
|
||||||
|
? new AgeTraits(
|
||||||
|
AgeTraits.BiomeDistribution.TILED,
|
||||||
|
selectedTraits.lighting(),
|
||||||
|
selectedTraits.weather(),
|
||||||
|
selectedTraits.celestialPeriod(),
|
||||||
|
selectedTraits.celestialAngle(),
|
||||||
|
selectedTraits.celestialPhase()
|
||||||
|
)
|
||||||
|
: selectedTraits;
|
||||||
AgeDefinition definition = new AgeDefinition(
|
AgeDefinition definition = new AgeDefinition(
|
||||||
id,
|
id,
|
||||||
"Profile " + profile.getPath(),
|
"Profile " + profile.getPath(),
|
||||||
@@ -166,16 +186,7 @@ public final class LinkingGameTests {
|
|||||||
Rivencraft.MOD_ID, "gametest/" + profile.getPath() + "_" + id
|
Rivencraft.MOD_ID, "gametest/" + profile.getPath() + "_" + id
|
||||||
),
|
),
|
||||||
null,
|
null,
|
||||||
profile.equals(AgeGenerationProfiles.STANDARD)
|
traits
|
||||||
? new AgeTraits(
|
|
||||||
AgeTraits.BiomeDistribution.SINGLE,
|
|
||||||
AgeTraits.Lighting.NORMAL,
|
|
||||||
AgeTraits.Weather.NORMAL,
|
|
||||||
1.0D,
|
|
||||||
0.0F,
|
|
||||||
0.0F
|
|
||||||
)
|
|
||||||
: AgeTraits.select(id.getMostSignificantBits())
|
|
||||||
);
|
);
|
||||||
var level = AgeDimensionService.ensureLoaded(helper.getLevel().getServer(), definition);
|
var level = AgeDimensionService.ensureLoaded(helper.getLevel().getServer(), definition);
|
||||||
helper.assertTrue(level != null, "The " + profile + " profile must load a runtime dimension");
|
helper.assertTrue(level != null, "The " + profile + " profile must load a runtime dimension");
|
||||||
@@ -192,6 +203,21 @@ public final class LinkingGameTests {
|
|||||||
"Single Biome Distribution must expose exactly one biome"
|
"Single Biome Distribution must expose exactly one biome"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (profile.equals(AgeGenerationProfiles.AMPLIFIED)) {
|
||||||
|
var biomeSource = level.getChunkSource().getGenerator().getBiomeSource();
|
||||||
|
helper.assertValueEqual(
|
||||||
|
biomeSource.possibleBiomes().size(),
|
||||||
|
2,
|
||||||
|
"Tiled Biome Distribution must expose exactly two seeded biomes"
|
||||||
|
);
|
||||||
|
var origin = biomeSource.getNoiseBiome(0, 0, 0, null);
|
||||||
|
var eastTile = biomeSource.getNoiseBiome(64, 0, 0, null);
|
||||||
|
var diagonalTile = biomeSource.getNoiseBiome(64, 0, 64, null);
|
||||||
|
helper.assertFalse(origin.equals(eastTile),
|
||||||
|
"Adjacent 256-block Tiled squares must alternate biomes");
|
||||||
|
helper.assertTrue(origin.equals(diagonalTile),
|
||||||
|
"Diagonal 256-block Tiled squares must repeat the biome");
|
||||||
|
}
|
||||||
if (definition.traits().lighting() == AgeTraits.Lighting.DARK) {
|
if (definition.traits().lighting() == AgeTraits.Lighting.DARK) {
|
||||||
helper.assertFalse(level.dimensionType().hasSkyLight(),
|
helper.assertFalse(level.dimensionType().hasSkyLight(),
|
||||||
"Dark Lighting Ages must suppress dimension skylight");
|
"Dark Lighting Ages must suppress dimension skylight");
|
||||||
|
|||||||
Reference in new issue
Block a user