Redesign linking book interface
Build / build (push) Canceled after 0s

This commit is contained in:
dnorberg committed 2026-09-21 07:41:01 -04:00
1 parent 2a496524ba
commit 1878a073c5
6 files changed
+63 -29

No files matched your search

+2 -2
View File
@@ -14,8 +14,8 @@ been ported yet.
Craft a Linking Book from a vanilla book and an ender pearl, then use it in the
air. An unbound book opens a screen where it can be named and bound to the
current location. A bound book opens its destination screen and travels only
when the Link button is pressed. The destination is stored on the item and
current location. A bound book opens its destination screen and travels when
its preview panel is clicked. The destination is stored on the item and
survives inventory and world saves. Travel only succeeds if the target
dimension is loaded and a solid, collision-free landing position can be found
nearby.
+5
View File
@@ -84,6 +84,11 @@ Version 0.1.5 ensures the book interaction listener opens screens only for the
logical-client event. This avoids calling the render system from the integrated
server thread when a book is used in singleplayer.
Version 0.1.6 gives the Linking Book screen an open-book layout inspired by the
legacy interface. The destination preview occupies the left page, the book name
and destination details occupy the right page, and the preview itself is the
link action; the separate Link and Done buttons have been removed.
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
View File
@@ -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.5
mod_version=0.1.6
# 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
@@ -13,13 +13,23 @@ import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.network.PacketDistributor;
public final class LinkingBookScreen extends Screen {
private static final int PANEL_WIDTH = 180;
private static final int PREVIEW_HEIGHT = 100;
private static final ResourceLocation BOOK_TEXTURE = ResourceLocation.fromNamespaceAndPath(
"rivencraft", "textures/gui/linking_book.png"
);
private static final int BOOK_WIDTH = 327;
private static final int BOOK_HEIGHT = 199;
private static final int TEXTURE_WIDTH = 512;
private static final int TEXTURE_HEIGHT = 312;
private static final int PREVIEW_X = 28;
private static final int PREVIEW_Y = 35;
private static final int PREVIEW_WIDTH = 126;
private static final int PREVIEW_HEIGHT = 86;
private final InteractionHand hand;
private final ItemStack book;
@@ -36,29 +46,24 @@ public final class LinkingBookScreen extends Screen {
@Override
protected void init() {
int left = (width - PANEL_WIDTH) / 2;
int buttonY = height / 2 + 72;
int left = (width - BOOK_WIDTH) / 2;
int top = (height - BOOK_HEIGHT) / 2;
if (target == null) {
titleInput = new EditBox(font, left, height / 2 - 10, PANEL_WIDTH, 20,
int rightPage = left + 177;
titleInput = new EditBox(font, rightPage, top + 69, 124, 20,
Component.translatable("screen.rivencraft.book.title"));
titleInput.setMaxLength(ModNetworking.MAX_BOOK_TITLE_LENGTH);
titleInput.setHint(Component.translatable("screen.rivencraft.book.title_hint"));
addRenderableWidget(titleInput);
setInitialFocus(titleInput);
addRenderableWidget(Button.builder(Component.translatable("screen.rivencraft.book.bind"), button -> bind())
.bounds(left, height / 2 + 20, 86, 20)
.bounds(rightPage, top + 100, 59, 20)
.build());
addRenderableWidget(Button.builder(Component.translatable("gui.cancel"), button -> onClose())
.bounds(left + 94, height / 2 + 20, 86, 20)
.bounds(rightPage + 65, top + 100, 59, 20)
.build());
} else {
preview = new PonderDestinationPreviewRenderer();
addRenderableWidget(Button.builder(Component.translatable("screen.rivencraft.book.link"), button -> link())
.bounds(left, buttonY, 86, 20)
.build());
addRenderableWidget(Button.builder(Component.translatable("gui.done"), button -> onClose())
.bounds(left + 94, buttonY, 86, 20)
.build());
}
}
@@ -71,22 +76,45 @@ public final class LinkingBookScreen extends Screen {
@Override
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
super.render(graphics, mouseX, mouseY, partialTick);
int centerX = width / 2;
graphics.drawCenteredString(font, title, centerX, height / 2 - 82, 0xFFFFFFFF);
int left = (width - BOOK_WIDTH) / 2;
int top = (height - BOOK_HEIGHT) / 2;
graphics.blit(BOOK_TEXTURE, left, top, BOOK_WIDTH, BOOK_HEIGHT, 0, 0,
TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_WIDTH, TEXTURE_HEIGHT);
if (target == null) {
graphics.drawCenteredString(font, Component.translatable("screen.rivencraft.book.name_prompt"),
centerX, height / 2 - 34, 0xFFB8B8B8);
return;
graphics.drawWordWrap(font, Component.translatable("screen.rivencraft.book.name_prompt"),
left + 177, top + 45, 124, 0xFF3B281B);
} else {
int previewLeft = left + PREVIEW_X;
int previewTop = top + PREVIEW_Y;
preview.render(graphics, previewLeft, previewTop, PREVIEW_WIDTH, PREVIEW_HEIGHT, partialTick);
int rightCenter = left + 239;
graphics.drawWordWrap(font, title, left + 177, top + 43, 124, 0xFF3B281B);
BlockPos pos = target.location().pos();
graphics.drawCenteredString(font, Component.literal(target.location().dimension().location().toString()),
rightCenter, top + 76, 0xFF624934);
graphics.drawCenteredString(font, Component.literal(pos.getX() + ", " + pos.getY() + ", " + pos.getZ()),
rightCenter, top + 89, 0xFF624934);
graphics.drawCenteredString(font, Component.translatable("screen.rivencraft.book.click_to_link"),
rightCenter, top + 119, 0xFF7A5A39);
}
int left = (width - PANEL_WIDTH) / 2;
int previewTop = height / 2 - 60;
preview.render(graphics, left, previewTop, PANEL_WIDTH, PREVIEW_HEIGHT, partialTick);
BlockPos pos = target.location().pos();
graphics.drawCenteredString(font, Component.literal(
target.location().dimension().location() + " " + pos.getX() + ", " + pos.getY() + ", " + pos.getZ()),
centerX, previewTop + PREVIEW_HEIGHT + 8, 0xFFB8B8B8);
super.render(graphics, mouseX, mouseY, partialTick);
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (target != null && button == 0) {
int left = (width - BOOK_WIDTH) / 2 + PREVIEW_X;
int top = (height - BOOK_HEIGHT) / 2 + PREVIEW_Y;
if (mouseX >= left && mouseX < left + PREVIEW_WIDTH
&& mouseY >= top && mouseY < top + PREVIEW_HEIGHT) {
link();
return true;
}
}
return super.mouseClicked(mouseX, mouseY, button);
}
@Override
@@ -18,5 +18,6 @@
"screen.rivencraft.book.link": "Link",
"screen.rivencraft.book.unwritten": "This Descriptive Book is unwritten",
"screen.rivencraft.book.preview_pending": "Ponder preview loading",
"screen.rivencraft.book.click_to_link": "Click the panel to link",
"itemGroup.rivencraft": "Rivencraft"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB