Keep Cave Age spawns below the roof
Build / build (push) Canceled after 0s

This commit is contained in:
dnorberg committed 2026-09-22 16:27:56 -04:00
1 parent 31ba6f9c15
commit 251d0a2de8
3 files changed
+27 -7

No files matched your search

+5
View File
@@ -276,6 +276,11 @@ dimension skylight while retaining local block light. The latter is the closest
server-safe modern equivalent to Legacy's removed per-dimension light-table
scaling hook.
Version 0.2.18.1 prevents Cave Ages from choosing a spawn on their upper roof.
Their grounded arrival search now begins with the floor below player Y=64 and
works downward. If it finds no suitable footing, the existing floor-Y=63
platform fallback places the player at Y=64.
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
on a Book Stand. Return Linking Books created inside another Age also retain and
+1 -1
View File
@@ -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.
mod_license=LGPL-3.0-or-later
# The mod version. Rivencraft uses the x.y.z.b policy documented in README.md.
mod_version=0.2.18.0
mod_version=0.2.18.1
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.
# This should match the base package used for the mod sources.
@@ -37,6 +37,7 @@ public final class AgeDimensionService {
private static final int PLATFORM_RADIUS = 2;
private static final int SURFACE_SEARCH_RADIUS = 16;
private static final int FALLBACK_PLATFORM_Y = 63;
private static final int CAVE_SPAWN_SEARCH_Y = 64;
private AgeDimensionService() {
}
@@ -64,7 +65,7 @@ public final class AgeDimensionService {
BlockPos spawn = definition.spawn();
if (spawn == null) {
spawn = createSafeSpawn(level);
spawn = createSafeSpawn(level, definition);
definition = AgeRegistrySavedData.get(level).setSpawn(definition.id(), spawn);
}
return Optional.of(new LinkTarget(
@@ -105,10 +106,19 @@ public final class AgeDimensionService {
return ResourceKey.create(net.minecraft.core.registries.Registries.DIMENSION, definition.dimensionId());
}
private static BlockPos createSafeSpawn(ServerLevel level) {
BlockPos floorCenter = isNetherStyle(level)
? netherSpawnFloor(level)
: highestFootedSurface(level).orElseGet(() -> fallbackSpawnFloor(level));
private static BlockPos createSafeSpawn(ServerLevel level, AgeDefinition age) {
BlockPos floorCenter;
if (age.generationProfile().equals(AgeGenerationProfiles.CAVE)) {
// Cave Ages are enclosed. Searching from the world ceiling would
// select or expose their roof, so begin with the floor beneath a
// player standing at Y=64 and search downward from there.
floorCenter = highestFootedSurface(level, CAVE_SPAWN_SEARCH_Y - 1)
.orElseGet(() -> fallbackSpawnFloor(level));
} else if (isNetherStyle(level)) {
floorCenter = netherSpawnFloor(level);
} else {
floorCenter = highestFootedSurface(level).orElseGet(() -> fallbackSpawnFloor(level));
}
for (int x = -PLATFORM_RADIUS; x <= PLATFORM_RADIUS; x++) {
for (int z = -PLATFORM_RADIUS; z <= PLATFORM_RADIUS; z++) {
@@ -138,8 +148,13 @@ public final class AgeDimensionService {
/** Selects the highest nearby terrain column that can naturally support a player. */
private static Optional<BlockPos> highestFootedSurface(ServerLevel level) {
return highestFootedSurface(level, level.getMaxBuildHeight() - 5);
}
private static Optional<BlockPos> highestFootedSurface(ServerLevel level, int requestedMaximumFloorY) {
BlockPos best = null;
int maximumFloorY = level.getMaxBuildHeight() - 5;
int maximumFloorY = Math.clamp(requestedMaximumFloorY,
level.getMinBuildHeight(), level.getMaxBuildHeight() - 5);
for (int x = -SURFACE_SEARCH_RADIUS; x <= SURFACE_SEARCH_RADIUS; x++) {
for (int z = -SURFACE_SEARCH_RADIUS; z <= SURFACE_SEARCH_RADIUS; z++) {