Public Access
This commit is contained in:
1 parent
8bb5e16720
commit
2b18f776f2
8 files changed
+77
-12
No files matched your search
@@ -13,6 +13,7 @@ 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.dnorberg.rivencraft.book.AgeCelestialService;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.fml.ModContainer;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
@@ -38,6 +39,7 @@ public final class Rivencraft {
|
||||
ModCreativeTabs.register(modEventBus);
|
||||
NeoForge.EVENT_BUS.addListener(BookStandConversionHandler::onRightClickBlock);
|
||||
NeoForge.EVENT_BUS.addListener(AgeWeatherService::onLevelTickPost);
|
||||
NeoForge.EVENT_BUS.addListener(AgeCelestialService::onLevelTickPost);
|
||||
LOGGER.info("Initializing Rivencraft");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package net.dnorberg.rivencraft.book;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.neoforged.neoforge.event.tick.LevelTickEvent;
|
||||
|
||||
/** Holds Zero Length Age clocks without changing the server-wide daylight gamerule. */
|
||||
public final class AgeCelestialService {
|
||||
private static final Map<ServerLevel, Long> FROZEN_TIMES = new WeakHashMap<>();
|
||||
|
||||
private AgeCelestialService() {
|
||||
}
|
||||
|
||||
public static void freezeAt(ServerLevel level, long dayTime) {
|
||||
FROZEN_TIMES.put(level, dayTime);
|
||||
}
|
||||
|
||||
public static void unfreeze(ServerLevel level) {
|
||||
FROZEN_TIMES.remove(level);
|
||||
}
|
||||
|
||||
public static void onLevelTickPost(LevelTickEvent.Post event) {
|
||||
if (event.getLevel() instanceof ServerLevel level) {
|
||||
Long frozenTime = FROZEN_TIMES.get(level);
|
||||
if (frozenTime != null && level.getDayTime() != frozenTime) {
|
||||
level.setDayTime(frozenTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 = 6;
|
||||
public static final int CURRENT_GENERATION_VERSION = 7;
|
||||
|
||||
public AgeDefinition {
|
||||
Objects.requireNonNull(id, "id");
|
||||
|
||||
@@ -103,12 +103,21 @@ public final class AgeDimensionService {
|
||||
}
|
||||
|
||||
private static void applyCelestialClock(ServerLevel level, AgeDefinition age) {
|
||||
level.setDayTimePerTick((float)(1.0D / age.traits().celestialPeriod()));
|
||||
if (age.traits().hasStoppedCelestialCycle()) {
|
||||
level.setDayTimePerTick(-1.0F);
|
||||
AgeCelestialService.freezeAt(level, level.getDayTime());
|
||||
} else {
|
||||
AgeCelestialService.unfreeze(level);
|
||||
level.setDayTimePerTick((float)(1.0D / age.traits().celestialPeriod()));
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyInitialCelestialPhase(ServerLevel level, AgeDefinition age) {
|
||||
long phaseTime = (long)(age.traits().celestialPhase() * Level.TICKS_PER_DAY);
|
||||
level.setDayTime(phaseTime);
|
||||
if (age.traits().hasStoppedCelestialCycle()) {
|
||||
AgeCelestialService.freezeAt(level, phaseTime);
|
||||
}
|
||||
}
|
||||
|
||||
private static void synchronizeImmersivePortals(MinecraftServer server) {
|
||||
|
||||
@@ -13,6 +13,7 @@ public record AgeTraits(
|
||||
) {
|
||||
public static final double MIN_CELESTIAL_PERIOD = 0.2D;
|
||||
public static final double MAX_CELESTIAL_PERIOD = 2.0D;
|
||||
public static final double STOPPED_CELESTIAL_PERIOD = 0.0D;
|
||||
public static final float MIN_CELESTIAL_ANGLE = 0.0F;
|
||||
public static final float MAX_CELESTIAL_ANGLE = 360.0F;
|
||||
public static final float MIN_CELESTIAL_PHASE = 0.0F;
|
||||
@@ -27,7 +28,8 @@ public record AgeTraits(
|
||||
if (biomeDistribution == null || lighting == null || weather == null) {
|
||||
throw new IllegalArgumentException("Age trait choices cannot be null");
|
||||
}
|
||||
if (celestialPeriod < MIN_CELESTIAL_PERIOD || celestialPeriod > MAX_CELESTIAL_PERIOD) {
|
||||
if (celestialPeriod != STOPPED_CELESTIAL_PERIOD
|
||||
&& (celestialPeriod < MIN_CELESTIAL_PERIOD || celestialPeriod > MAX_CELESTIAL_PERIOD)) {
|
||||
throw new IllegalArgumentException("Celestial period is outside the legacy range");
|
||||
}
|
||||
if (celestialAngle < MIN_CELESTIAL_ANGLE || celestialAngle >= MAX_CELESTIAL_ANGLE) {
|
||||
@@ -40,17 +42,27 @@ public record AgeTraits(
|
||||
|
||||
public static AgeTraits select(long seed) {
|
||||
Random random = new Random(seed ^ 0x524956454E435241L);
|
||||
BiomeDistribution biomeDistribution = randomChoice(random, BiomeDistribution.values());
|
||||
Lighting lighting = randomChoice(random, Lighting.values());
|
||||
Weather weather = randomChoice(random, Weather.values());
|
||||
// Legacy's PERIOD_BASIC grammar gives ModZero rank 2 and its other
|
||||
// three length modifiers rank 1, producing an effective 1-in-7 weight.
|
||||
boolean stopped = random.nextInt(7) == 0;
|
||||
return new AgeTraits(
|
||||
randomChoice(random, BiomeDistribution.values()),
|
||||
randomChoice(random, Lighting.values()),
|
||||
randomChoice(random, Weather.values()),
|
||||
MIN_CELESTIAL_PERIOD
|
||||
biomeDistribution,
|
||||
lighting,
|
||||
weather,
|
||||
stopped ? STOPPED_CELESTIAL_PERIOD : MIN_CELESTIAL_PERIOD
|
||||
+ random.nextDouble() * (MAX_CELESTIAL_PERIOD - MIN_CELESTIAL_PERIOD),
|
||||
random.nextFloat() * MAX_CELESTIAL_ANGLE,
|
||||
random.nextFloat()
|
||||
);
|
||||
}
|
||||
|
||||
public boolean hasStoppedCelestialCycle() {
|
||||
return celestialPeriod == STOPPED_CELESTIAL_PERIOD;
|
||||
}
|
||||
|
||||
public static <E extends Enum<E>> E parseOrDefault(String value, E fallback) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -121,7 +121,8 @@ public final class LinkingGameTests {
|
||||
"New Ages must record the current generation algorithm version");
|
||||
helper.assertValueEqual(first.traits(), AgeTraits.select(first.seed()),
|
||||
"A page-free book must persist the deterministic traits selected from its seed");
|
||||
helper.assertTrue(first.traits().celestialPeriod() >= AgeTraits.MIN_CELESTIAL_PERIOD
|
||||
helper.assertTrue(first.traits().hasStoppedCelestialCycle()
|
||||
|| first.traits().celestialPeriod() >= AgeTraits.MIN_CELESTIAL_PERIOD
|
||||
&& first.traits().celestialPeriod() <= AgeTraits.MAX_CELESTIAL_PERIOD,
|
||||
"The celestial period must remain inside Mystcraft Legacy's random range");
|
||||
helper.assertTrue(first.seed() != another.seed(), "Distinct Age UUIDs must receive distinct random seeds");
|
||||
@@ -186,9 +187,14 @@ public final class LinkingGameTests {
|
||||
? 0.25F : 0.0F;
|
||||
helper.assertTrue(Math.abs(level.dimensionType().ambientLight() - expectedAmbientLight) < 0.0001F,
|
||||
"The runtime dimension must apply the persisted lighting trait");
|
||||
float expectedDaySpeed = (float)(1.0D / definition.traits().celestialPeriod());
|
||||
helper.assertTrue(Math.abs(level.getDayTimePerTick() - expectedDaySpeed) < 0.0001F,
|
||||
"The runtime dimension must apply the persisted celestial period");
|
||||
if (definition.traits().hasStoppedCelestialCycle()) {
|
||||
helper.assertTrue(level.getDayTimePerTick() < 0.0F,
|
||||
"A Zero Length Age must leave vanilla clock advancement under the freeze controller");
|
||||
} else {
|
||||
float expectedDaySpeed = (float)(1.0D / definition.traits().celestialPeriod());
|
||||
helper.assertTrue(Math.abs(level.getDayTimePerTick() - expectedDaySpeed) < 0.0001F,
|
||||
"The runtime dimension must apply the persisted celestial period");
|
||||
}
|
||||
}
|
||||
helper.succeed();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user