Apply persisted Age weather traits
Build / build (push) Canceled after 0s

This commit is contained in:
dnorberg committed 2026-09-22 16:32:25 -04:00
1 parent 251d0a2de8
commit b65f9379e3
5 files changed
+83 -2

No files matched your search

+8
View File
@@ -281,6 +281,14 @@ 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.19.0 applies persisted weather traits to loaded Ages. Normal uses
Minecraft's normal weather cycle. Fast and Slow use Legacy's original duration
and cooldown ranges at half and double normal speed for Minecraft's combined
rain/thunder weather timer. Off keeps an Age clear;
Always, Cloudy, Rain, and Snow maintain non-thundering precipitation; Storm
maintains rain and thunder. Minecraft still chooses rain versus snow from biome
temperature, so dedicated Snow/Rain biome overrides remain future work.
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.1
mod_version=0.2.19.0
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.
@@ -12,6 +12,7 @@ import net.dnorberg.rivencraft.network.ModNetworking;
import net.dnorberg.rivencraft.config.RivencraftConfig;
import net.dnorberg.rivencraft.config.RivencraftClientConfig;
import net.dnorberg.rivencraft.book.AgeDimensionService;
import net.dnorberg.rivencraft.book.AgeWeatherService;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.ModContainer;
import net.neoforged.fml.common.Mod;
@@ -36,6 +37,7 @@ public final class Rivencraft {
ModSounds.register(modEventBus);
ModCreativeTabs.register(modEventBus);
NeoForge.EVENT_BUS.addListener(BookStandConversionHandler::onRightClickBlock);
NeoForge.EVENT_BUS.addListener(AgeWeatherService::onLevelTickPost);
LOGGER.info("Initializing Rivencraft");
}
}
@@ -21,7 +21,7 @@ public record AgeDefinition(
public static final ResourceLocation RANDOM_VANILLA_PROFILE = ResourceLocation.fromNamespaceAndPath(
Rivencraft.MOD_ID, "random_vanilla"
);
public static final int CURRENT_GENERATION_VERSION = 4;
public static final int CURRENT_GENERATION_VERSION = 5;
public AgeDefinition {
Objects.requireNonNull(id, "id");
@@ -0,0 +1,71 @@
package net.dnorberg.rivencraft.book;
import java.util.Map;
import java.util.WeakHashMap;
import net.dnorberg.rivencraft.Rivencraft;
import net.minecraft.server.level.ServerLevel;
import net.neoforged.neoforge.event.tick.LevelTickEvent;
/** Applies persisted Legacy-inspired weather behavior to loaded Ages. */
public final class AgeWeatherService {
private static final int FIXED_WEATHER_DURATION = 6000;
private static final Map<ServerLevel, WeatherState> STATES = new WeakHashMap<>();
private AgeWeatherService() {
}
public static void onLevelTickPost(LevelTickEvent.Post event) {
if (!(event.getLevel() instanceof ServerLevel level)
|| !level.dimension().location().getNamespace().equals(Rivencraft.MOD_ID)) {
return;
}
AgeDefinition age = AgeRegistrySavedData.get(level)
.findByDimension(level.dimension().location())
.orElse(null);
if (age == null) {
return;
}
AgeTraits.Weather weather = age.traits().weather();
if (weather == AgeTraits.Weather.NORMAL) {
STATES.remove(level);
return;
}
if (weather == AgeTraits.Weather.FAST || weather == AgeTraits.Weather.SLOW) {
applyVariableWeather(level, weather);
} else {
STATES.remove(level);
applyFixedWeather(level, weather);
}
}
private static void applyVariableWeather(
ServerLevel level,
AgeTraits.Weather weather
) {
WeatherState current = new WeatherState(level.isRaining(), level.isThundering());
WeatherState previous = STATES.put(level, current);
if (current.equals(previous)) {
return;
}
int scale = weather == AgeTraits.Weather.FAST ? 1 : 4;
int rainBase = 6000 * scale;
int rainRange = (current.raining() ? 6000 : 84000) * scale;
int duration = rainBase + level.getRandom().nextInt(rainRange);
level.setWeatherParameters(0, duration, current.raining(), current.thundering());
}
private static void applyFixedWeather(ServerLevel level, AgeTraits.Weather weather) {
boolean raining = weather != AgeTraits.Weather.OFF;
boolean thundering = weather == AgeTraits.Weather.STORM;
if (level.isRaining() != raining || level.isThundering() != thundering
|| level.getGameTime() % 200L == 0L) {
level.setWeatherParameters(0, FIXED_WEATHER_DURATION, raining, thundering);
}
}
private record WeatherState(boolean raining, boolean thundering) {
}
}