Public Access
1 parent
88af167f62
commit
08caa98c0b
10 files changed
+163
-4
No files matched your search
@@ -355,6 +355,11 @@ Age's selected terrain profile. End biome columns generate from End stone;
|
|||||||
Nether biome columns use Minecraft's Nether surface rules for netherrack,
|
Nether biome columns use Minecraft's Nether surface rules for netherrack,
|
||||||
soul sand, basalt, and nylium instead of inheriting Overworld blocks.
|
soul sand, basalt, and nylium instead of inheriting Overworld blocks.
|
||||||
|
|
||||||
|
Version 0.2.26.0 applies each Age's persisted celestial angle to the client
|
||||||
|
sky. The sun, moon, and stars follow a plane rotated by the saved Legacy-style
|
||||||
|
angle in normal gameplay and Immersive Portals previews, while vanilla
|
||||||
|
dimensions retain their standard celestial path.
|
||||||
|
|
||||||
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.25.1
|
mod_version=0.2.26.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.
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import net.dnorberg.rivencraft.registry.ModBlocks;
|
|||||||
import net.dnorberg.rivencraft.registry.ModBlockEntities;
|
import net.dnorberg.rivencraft.registry.ModBlockEntities;
|
||||||
import net.dnorberg.rivencraft.registry.ModBiomeSources;
|
import net.dnorberg.rivencraft.registry.ModBiomeSources;
|
||||||
import net.dnorberg.rivencraft.event.BookStandConversionHandler;
|
import net.dnorberg.rivencraft.event.BookStandConversionHandler;
|
||||||
|
import net.dnorberg.rivencraft.event.AgeCelestialAngleSync;
|
||||||
import net.dnorberg.rivencraft.network.ModNetworking;
|
import net.dnorberg.rivencraft.network.ModNetworking;
|
||||||
import net.dnorberg.rivencraft.config.RivencraftConfig;
|
import net.dnorberg.rivencraft.config.RivencraftConfig;
|
||||||
import net.dnorberg.rivencraft.config.RivencraftClientConfig;
|
import net.dnorberg.rivencraft.config.RivencraftClientConfig;
|
||||||
@@ -40,6 +41,8 @@ public final class Rivencraft {
|
|||||||
ModCreativeTabs.register(modEventBus);
|
ModCreativeTabs.register(modEventBus);
|
||||||
NeoForge.EVENT_BUS.addListener(BookStandConversionHandler::onRightClickBlock);
|
NeoForge.EVENT_BUS.addListener(BookStandConversionHandler::onRightClickBlock);
|
||||||
NeoForge.EVENT_BUS.addListener(AgeWeatherService::onLevelTickPost);
|
NeoForge.EVENT_BUS.addListener(AgeWeatherService::onLevelTickPost);
|
||||||
|
NeoForge.EVENT_BUS.addListener(AgeCelestialAngleSync::onPlayerLoggedIn);
|
||||||
|
NeoForge.EVENT_BUS.addListener(AgeCelestialAngleSync::onPlayerChangedDimension);
|
||||||
LOGGER.info("Initializing Rivencraft");
|
LOGGER.info("Initializing Rivencraft");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package net.dnorberg.rivencraft.client;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import net.dnorberg.rivencraft.network.AgeCelestialAnglePayload;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||||
|
|
||||||
|
/** Client cache used by both the active world and remote preview renderers. */
|
||||||
|
public final class ClientAgeCelestialAngles {
|
||||||
|
private static final Map<ResourceKey<Level>, Float> ANGLES = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private ClientAgeCelestialAngles() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void handle(AgeCelestialAnglePayload payload, IPayloadContext context) {
|
||||||
|
ANGLES.put(payload.dimension(), payload.angle());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float get(ResourceKey<Level> dimension) {
|
||||||
|
return ANGLES.getOrDefault(dimension, 0.0F);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package net.dnorberg.rivencraft.event;
|
||||||
|
|
||||||
|
import net.dnorberg.rivencraft.book.AgeDefinition;
|
||||||
|
import net.dnorberg.rivencraft.book.AgeDimensionService;
|
||||||
|
import net.dnorberg.rivencraft.book.AgeRegistrySavedData;
|
||||||
|
import net.dnorberg.rivencraft.network.AgeCelestialAnglePayload;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
|
||||||
|
import net.neoforged.neoforge.network.PacketDistributor;
|
||||||
|
import net.neoforged.neoforge.network.registration.NetworkRegistry;
|
||||||
|
|
||||||
|
/** Sends saved celestial angles when a client joins or enters an Age. */
|
||||||
|
public final class AgeCelestialAngleSync {
|
||||||
|
private AgeCelestialAngleSync() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) {
|
||||||
|
if (!(event.getEntity() instanceof ServerPlayer player)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (AgeDefinition age : AgeRegistrySavedData.get(player.serverLevel()).definitions()) {
|
||||||
|
send(player, age);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void onPlayerChangedDimension(PlayerEvent.PlayerChangedDimensionEvent event) {
|
||||||
|
if (!(event.getEntity() instanceof ServerPlayer player)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AgeRegistrySavedData.get(player.serverLevel()).definitions().stream()
|
||||||
|
.filter(age -> AgeDimensionService.dimensionKey(age).equals(event.getTo()))
|
||||||
|
.findFirst()
|
||||||
|
.ifPresent(age -> send(player, age));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void send(ServerPlayer player, AgeDefinition age) {
|
||||||
|
if (!NetworkRegistry.hasChannel(player.connection, AgeCelestialAnglePayload.TYPE.id())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PacketDistributor.sendToPlayer(player, new AgeCelestialAnglePayload(
|
||||||
|
AgeDimensionService.dimensionKey(age), age.traits().celestialAngle()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package net.dnorberg.rivencraft.mixin.client;
|
||||||
|
|
||||||
|
import com.mojang.math.Axis;
|
||||||
|
import net.dnorberg.rivencraft.client.ClientAgeCelestialAngles;
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
import net.minecraft.client.renderer.LevelRenderer;
|
||||||
|
import org.joml.Quaternionf;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
/** Tilts the vanilla sun, moon, and star plane by each Age's saved angle. */
|
||||||
|
@Mixin(LevelRenderer.class)
|
||||||
|
public abstract class LevelRendererMixin {
|
||||||
|
@Shadow
|
||||||
|
private ClientLevel level;
|
||||||
|
|
||||||
|
@Redirect(
|
||||||
|
method = "renderSky",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Lcom/mojang/math/Axis;rotationDegrees(F)Lorg/joml/Quaternionf;",
|
||||||
|
ordinal = 3
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private Quaternionf rivencraft$rotateCelestialPlane(Axis axis, float degrees) {
|
||||||
|
float angle = ClientAgeCelestialAngles.get(level.dimension());
|
||||||
|
return new Quaternionf(Axis.ZP.rotationDegrees(angle)).mul(axis.rotationDegrees(degrees));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package net.dnorberg.rivencraft.network;
|
||||||
|
|
||||||
|
import net.dnorberg.rivencraft.Rivencraft;
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||||
|
import net.minecraft.network.codec.StreamCodec;
|
||||||
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
|
||||||
|
/** Synchronizes an Age's saved celestial-plane rotation to clients. */
|
||||||
|
public record AgeCelestialAnglePayload(ResourceKey<Level> dimension, float angle)
|
||||||
|
implements CustomPacketPayload {
|
||||||
|
public static final Type<AgeCelestialAnglePayload> TYPE = new Type<>(
|
||||||
|
ResourceLocation.fromNamespaceAndPath(Rivencraft.MOD_ID, "age_celestial_angle")
|
||||||
|
);
|
||||||
|
public static final StreamCodec<RegistryFriendlyByteBuf, AgeCelestialAnglePayload> STREAM_CODEC =
|
||||||
|
StreamCodec.of(
|
||||||
|
(buffer, payload) -> {
|
||||||
|
buffer.writeResourceKey(payload.dimension());
|
||||||
|
buffer.writeFloat(payload.angle());
|
||||||
|
},
|
||||||
|
buffer -> new AgeCelestialAnglePayload(
|
||||||
|
buffer.readResourceKey(Registries.DIMENSION), buffer.readFloat())
|
||||||
|
);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type<? extends CustomPacketPayload> type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,8 @@ import net.dnorberg.rivencraft.book.AgeDimensionService;
|
|||||||
import net.dnorberg.rivencraft.block.entity.BookStandBlockEntity;
|
import net.dnorberg.rivencraft.block.entity.BookStandBlockEntity;
|
||||||
import net.dnorberg.rivencraft.client.ClientLinkPreviewHandler;
|
import net.dnorberg.rivencraft.client.ClientLinkPreviewHandler;
|
||||||
import net.dnorberg.rivencraft.client.ClientBookInteractionHandler;
|
import net.dnorberg.rivencraft.client.ClientBookInteractionHandler;
|
||||||
|
import net.dnorberg.rivencraft.client.ClientAgeCelestialAngles;
|
||||||
|
import net.dnorberg.rivencraft.event.AgeCelestialAngleSync;
|
||||||
import net.dnorberg.rivencraft.item.DescriptiveBookItem;
|
import net.dnorberg.rivencraft.item.DescriptiveBookItem;
|
||||||
import net.dnorberg.rivencraft.item.LinkingBookItem;
|
import net.dnorberg.rivencraft.item.LinkingBookItem;
|
||||||
import net.dnorberg.rivencraft.registry.ModDataComponents;
|
import net.dnorberg.rivencraft.registry.ModDataComponents;
|
||||||
@@ -46,7 +48,7 @@ public final class ModNetworking {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void register(RegisterPayloadHandlersEvent event) {
|
public static void register(RegisterPayloadHandlersEvent event) {
|
||||||
PayloadRegistrar registrar = event.registrar("8");
|
PayloadRegistrar registrar = event.registrar("9");
|
||||||
registrar.playToServer(RequestDescriptiveBookScreenPayload.TYPE, RequestDescriptiveBookScreenPayload.STREAM_CODEC,
|
registrar.playToServer(RequestDescriptiveBookScreenPayload.TYPE, RequestDescriptiveBookScreenPayload.STREAM_CODEC,
|
||||||
ModNetworking::requestDescriptiveBookScreen);
|
ModNetworking::requestDescriptiveBookScreen);
|
||||||
registrar.playToClient(OpenDescriptiveBookScreenPayload.TYPE, OpenDescriptiveBookScreenPayload.STREAM_CODEC,
|
registrar.playToClient(OpenDescriptiveBookScreenPayload.TYPE, OpenDescriptiveBookScreenPayload.STREAM_CODEC,
|
||||||
@@ -64,6 +66,8 @@ public final class ModNetworking {
|
|||||||
(payload, context) -> releaseLinkPreview(context));
|
(payload, context) -> releaseLinkPreview(context));
|
||||||
registrar.playToClient(LinkPreviewPayload.TYPE, LinkPreviewPayload.STREAM_CODEC,
|
registrar.playToClient(LinkPreviewPayload.TYPE, LinkPreviewPayload.STREAM_CODEC,
|
||||||
ClientLinkPreviewHandler::handle);
|
ClientLinkPreviewHandler::handle);
|
||||||
|
registrar.playToClient(AgeCelestialAnglePayload.TYPE, AgeCelestialAnglePayload.STREAM_CODEC,
|
||||||
|
ClientAgeCelestialAngles::handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void requestDescriptiveBookScreen(RequestDescriptiveBookScreenPayload payload, IPayloadContext context) {
|
private static void requestDescriptiveBookScreen(RequestDescriptiveBookScreenPayload payload, IPayloadContext context) {
|
||||||
@@ -222,6 +226,11 @@ public final class ModNetworking {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AgeRegistrySavedData.get(player.serverLevel()).definitions().stream()
|
||||||
|
.filter(age -> AgeDimensionService.dimensionKey(age).equals(target.location().dimension()))
|
||||||
|
.findFirst()
|
||||||
|
.ifPresent(age -> AgeCelestialAngleSync.send(player, age));
|
||||||
|
|
||||||
ServerLevel level = player.getServer().getLevel(target.location().dimension());
|
ServerLevel level = player.getServer().getLevel(target.location().dimension());
|
||||||
if (level == null) {
|
if (level == null) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"required": true,
|
||||||
|
"minVersion": "0.8",
|
||||||
|
"package": "net.dnorberg.rivencraft.mixin",
|
||||||
|
"compatibilityLevel": "JAVA_21",
|
||||||
|
"client": [
|
||||||
|
"client.LevelRendererMixin"
|
||||||
|
],
|
||||||
|
"injectors": {
|
||||||
|
"defaultRequire": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -50,8 +50,8 @@ A spiritual successor and modern port of Mystcraft for Minecraft 1.21.1 on NeoFo
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
# The [[mixins]] block allows you to declare your mixin config to FML so that it gets loaded.
|
# The [[mixins]] block allows you to declare your mixin config to FML so that it gets loaded.
|
||||||
#[[mixins]]
|
[[mixins]]
|
||||||
#config="${mod_id}.mixins.json"
|
config="${mod_id}.mixins.json"
|
||||||
|
|
||||||
# The [[accessTransformers]] block allows you to declare where your AT file is.
|
# The [[accessTransformers]] block allows you to declare where your AT file is.
|
||||||
# If this block is omitted, a fallback attempt will be made to load an AT from META-INF/accesstransformer.cfg
|
# If this block is omitted, a fallback attempt will be made to load an AT from META-INF/accesstransformer.cfg
|
||||||
|
|||||||
Reference in new issue
Block a user