Public Access
This commit is contained in:
1 parent
7b3bc328f2
commit
f57afab363
8 files changed
+89
-9
No files matched your search
+5
-1
@@ -53,7 +53,7 @@ the symbol grammar is introduced.
|
||||
- [x] Ponder dependency and isolated destination-preview level boundary.
|
||||
- [ ] Server-provided destination snapshots rendered as rotating Ponder scenes.
|
||||
- [x] Book Stand floating names synchronized from the stored book stack.
|
||||
- [ ] Open the stored book screen from a Book Stand.
|
||||
- [x] Open the stored book screen from a Book Stand with server-validated linking.
|
||||
- [ ] Automated in-game tests for binding, persistence, and travel.
|
||||
|
||||
The temporary shapeless Linking Book recipe makes the linking subsystem easy
|
||||
@@ -103,6 +103,10 @@ its display name as a camera-facing label above the book.
|
||||
Version 0.1.10 corrects the nameplate transform and matches Minecraft's normal
|
||||
plus see-through text passes so angled stand geometry cannot hide the label.
|
||||
|
||||
Version 0.1.11 opens the stored book interface when a Book Stand is used with
|
||||
an empty hand. Linking Books travel through the preview panel, and the server
|
||||
revalidates the stand position, interaction distance, stored item, and target.
|
||||
|
||||
The preview code is separated behind a renderer interface and uses an isolated
|
||||
Ponder level. The first iteration supplies the animated loading boundary; the
|
||||
next iteration will add server-authoritative snapshot transport and populate
|
||||
|
||||
+1
-1
@@ -33,7 +33,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. See https://semver.org/
|
||||
mod_version=0.1.10
|
||||
mod_version=0.1.11
|
||||
# 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.
|
||||
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
|
||||
@@ -2,9 +2,7 @@ package net.dnorberg.rivencraft.block;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import net.dnorberg.rivencraft.block.entity.BookStandBlockEntity;
|
||||
import net.dnorberg.rivencraft.item.LinkingBookItem;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
@@ -63,10 +61,6 @@ public final class BookStandBlock extends LecternBlock {
|
||||
return InteractionResult.sidedSuccess(level.isClientSide);
|
||||
}
|
||||
|
||||
ItemStack book = stand.getBook();
|
||||
if (book.getItem() instanceof LinkingBookItem && player instanceof ServerPlayer serverPlayer) {
|
||||
LinkingBookItem.useBoundBook(serverPlayer, book);
|
||||
}
|
||||
return InteractionResult.sidedSuccess(level.isClientSide);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,12 @@ package net.dnorberg.rivencraft.client;
|
||||
|
||||
import net.dnorberg.rivencraft.client.screen.LinkingBookScreen;
|
||||
import net.dnorberg.rivencraft.client.screen.DescriptiveBookScreen;
|
||||
import net.dnorberg.rivencraft.block.entity.BookStandBlockEntity;
|
||||
import net.dnorberg.rivencraft.registry.ModBlocks;
|
||||
import net.dnorberg.rivencraft.registry.ModItems;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
|
||||
|
||||
public final class ClientBookInteractionHandler {
|
||||
@@ -32,4 +35,27 @@ public final class ClientBookInteractionHandler {
|
||||
Minecraft.getInstance().setScreen(new DescriptiveBookScreen(event.getItemStack().copy()));
|
||||
}
|
||||
}
|
||||
|
||||
public static void onRightClickBlock(PlayerInteractEvent.RightClickBlock event) {
|
||||
if (!event.getEntity().level().isClientSide()
|
||||
|| event.getEntity().isShiftKeyDown()
|
||||
|| !event.getItemStack().isEmpty()
|
||||
|| !event.getLevel().getBlockState(event.getPos()).is(ModBlocks.BOOK_STAND.get())
|
||||
|| !(event.getLevel().getBlockEntity(event.getPos()) instanceof BookStandBlockEntity stand)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack book = stand.getBook();
|
||||
if (book.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCanceled(true);
|
||||
event.setCancellationResult(InteractionResult.SUCCESS);
|
||||
if (book.is(ModItems.LINKING_BOOK.get())) {
|
||||
Minecraft.getInstance().setScreen(new LinkingBookScreen(event.getPos(), book.copy()));
|
||||
} else if (book.is(ModItems.DESCRIPTIVE_BOOK.get())) {
|
||||
Minecraft.getInstance().setScreen(new DescriptiveBookScreen(book.copy()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,5 +22,6 @@ public final class ClientEvents {
|
||||
@SubscribeEvent
|
||||
public static void clientSetup(FMLClientSetupEvent event) {
|
||||
NeoForge.EVENT_BUS.addListener(ClientBookInteractionHandler::onRightClickItem);
|
||||
NeoForge.EVENT_BUS.addListener(ClientBookInteractionHandler::onRightClickBlock);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import net.dnorberg.rivencraft.client.preview.PonderDestinationPreviewRenderer;
|
||||
import net.dnorberg.rivencraft.network.BindLinkingBookPayload;
|
||||
import net.dnorberg.rivencraft.network.ModNetworking;
|
||||
import net.dnorberg.rivencraft.network.UseLinkingBookPayload;
|
||||
import net.dnorberg.rivencraft.network.UseBookStandPayload;
|
||||
import net.dnorberg.rivencraft.registry.ModDataComponents;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
@@ -35,6 +36,7 @@ public final class LinkingBookScreen extends Screen {
|
||||
private final InteractionHand hand;
|
||||
private final ItemStack book;
|
||||
private final LinkTarget target;
|
||||
private final BlockPos bookStandPos;
|
||||
private DestinationPreviewRenderer preview;
|
||||
private EditBox titleInput;
|
||||
|
||||
@@ -43,6 +45,15 @@ public final class LinkingBookScreen extends Screen {
|
||||
this.hand = hand;
|
||||
this.book = book;
|
||||
target = book.get(ModDataComponents.LINK_TARGET.get());
|
||||
bookStandPos = null;
|
||||
}
|
||||
|
||||
public LinkingBookScreen(BlockPos bookStandPos, ItemStack book) {
|
||||
super(book.getHoverName());
|
||||
hand = InteractionHand.MAIN_HAND;
|
||||
this.book = book;
|
||||
target = book.get(ModDataComponents.LINK_TARGET.get());
|
||||
this.bookStandPos = bookStandPos.immutable();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -140,7 +151,11 @@ public final class LinkingBookScreen extends Screen {
|
||||
}
|
||||
|
||||
private void link() {
|
||||
PacketDistributor.sendToServer(new UseLinkingBookPayload(hand == InteractionHand.OFF_HAND));
|
||||
if (bookStandPos == null) {
|
||||
PacketDistributor.sendToServer(new UseLinkingBookPayload(hand == InteractionHand.OFF_HAND));
|
||||
} else {
|
||||
PacketDistributor.sendToServer(new UseBookStandPayload(bookStandPos));
|
||||
}
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.dnorberg.rivencraft.network;
|
||||
|
||||
import net.dnorberg.rivencraft.book.LinkTarget;
|
||||
import net.dnorberg.rivencraft.block.entity.BookStandBlockEntity;
|
||||
import net.dnorberg.rivencraft.item.LinkingBookItem;
|
||||
import net.dnorberg.rivencraft.registry.ModDataComponents;
|
||||
import net.dnorberg.rivencraft.registry.ModItems;
|
||||
@@ -11,6 +12,7 @@ import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
|
||||
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||
import net.neoforged.neoforge.network.registration.PayloadRegistrar;
|
||||
@@ -25,6 +27,7 @@ public final class ModNetworking {
|
||||
PayloadRegistrar registrar = event.registrar("1");
|
||||
registrar.playToServer(BindLinkingBookPayload.TYPE, BindLinkingBookPayload.STREAM_CODEC, ModNetworking::bindBook);
|
||||
registrar.playToServer(UseLinkingBookPayload.TYPE, UseLinkingBookPayload.STREAM_CODEC, ModNetworking::useBook);
|
||||
registrar.playToServer(UseBookStandPayload.TYPE, UseBookStandPayload.STREAM_CODEC, ModNetworking::useBookStand);
|
||||
}
|
||||
|
||||
private static void bindBook(BindLinkingBookPayload payload, IPayloadContext context) {
|
||||
@@ -59,6 +62,19 @@ public final class ModNetworking {
|
||||
}
|
||||
}
|
||||
|
||||
private static void useBookStand(UseBookStandPayload payload, IPayloadContext context) {
|
||||
if (!(context.player() instanceof ServerPlayer player)
|
||||
|| player.distanceToSqr(Vec3.atCenterOf(payload.pos())) > 64.0D
|
||||
|| !(player.level().getBlockEntity(payload.pos()) instanceof BookStandBlockEntity stand)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack stack = stand.getBook();
|
||||
if (stack.is(ModItems.LINKING_BOOK.get()) && stack.has(ModDataComponents.LINK_TARGET.get())) {
|
||||
LinkingBookItem.useBoundBook(player, stack);
|
||||
}
|
||||
}
|
||||
|
||||
private static InteractionHand hand(boolean offhand) {
|
||||
return offhand ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package net.dnorberg.rivencraft.network;
|
||||
|
||||
import net.dnorberg.rivencraft.Rivencraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public record UseBookStandPayload(BlockPos pos) implements CustomPacketPayload {
|
||||
public static final Type<UseBookStandPayload> TYPE = new Type<>(
|
||||
ResourceLocation.fromNamespaceAndPath(Rivencraft.MOD_ID, "use_book_stand")
|
||||
);
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, UseBookStandPayload> STREAM_CODEC = StreamCodec.composite(
|
||||
BlockPos.STREAM_CODEC,
|
||||
UseBookStandPayload::pos,
|
||||
UseBookStandPayload::new
|
||||
);
|
||||
|
||||
@Override
|
||||
public Type<? extends CustomPacketPayload> type() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user