From 02901c9cbc4ba93385bc7a903493724dd667998f Mon Sep 17 00:00:00 2001 From: Dustin Norberg Date: Thu, 24 Sep 2026 04:46:51 -0400 Subject: [PATCH] Remove notebook rename flow and add Pages creative tab --- gradle.properties | 2 +- .../client/screen/NotebookScreen.java | 58 ++----------------- .../gametest/WritingDataGameTests.java | 7 ++- .../rivencraft/menu/NotebookMenu.java | 19 ------ .../rivencraft/network/ModNetworking.java | 13 ----- .../network/RenameNotebookPagePayload.java | 20 ------- .../rivencraft/registry/ModCreativeTabs.java | 12 +++- .../assets/rivencraft/lang/en_us.json | 5 +- 8 files changed, 22 insertions(+), 114 deletions(-) delete mode 100644 src/main/java/net/dnorberg/rivencraft/network/RenameNotebookPagePayload.java diff --git a/gradle.properties b/gradle.properties index 2be7fdc..e7ac29e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -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.3.4.0 +mod_version=0.3.4.1 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. diff --git a/src/main/java/net/dnorberg/rivencraft/client/screen/NotebookScreen.java b/src/main/java/net/dnorberg/rivencraft/client/screen/NotebookScreen.java index 23a61cf..50ced28 100644 --- a/src/main/java/net/dnorberg/rivencraft/client/screen/NotebookScreen.java +++ b/src/main/java/net/dnorberg/rivencraft/client/screen/NotebookScreen.java @@ -4,18 +4,15 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; import net.dnorberg.rivencraft.menu.NotebookMenu; -import net.dnorberg.rivencraft.network.RenameNotebookPagePayload; import net.dnorberg.rivencraft.registry.ModItems; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.EditBox; -import net.minecraft.client.gui.components.Tooltip; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.network.chat.Component; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.ClickType; import net.minecraft.world.item.ItemStack; -import net.neoforged.neoforge.network.PacketDistributor; /** A page surface modelled on Legacy's folder GUI, backed by the Notebook menu. */ public final class NotebookScreen extends AbstractContainerScreen { @@ -28,7 +25,6 @@ public final class NotebookScreen extends AbstractContainerScreen private static final int PAGE_STEP_Y = 41; private static final int PAGE_COLUMNS = 5; private EditBox textInput; - private boolean renaming; private boolean draggingScrollbar; private boolean surfaceClickPendingRelease; private int selectedSlot = -1; @@ -52,18 +48,12 @@ public final class NotebookScreen extends AbstractContainerScreen allButton.active = false; addRenderableWidget(sortButton); addRenderableWidget(allButton); - textInput = new EditBox(font, leftPos + 48, topPos, 86, 18, + textInput = new EditBox(font, leftPos + 48, topPos, 128, 18, Component.translatable("screen.rivencraft.notebook.search")); textInput.setMaxLength(32); textInput.setHint(Component.translatable("screen.rivencraft.notebook.search")); - textInput.setResponder(value -> { - if (!renaming) scroll = 0; - }); + textInput.setResponder(value -> scroll = 0); addRenderableWidget(textInput); - addRenderableWidget(Button.builder(Component.literal("R"), button -> toggleRename()) - .bounds(leftPos + 136, topPos, 18, 18) - .tooltip(Tooltip.create(Component.translatable("screen.rivencraft.notebook.rename_toggle"))) - .build()); } @Override @@ -120,7 +110,6 @@ public final class NotebookScreen extends AbstractContainerScreen if (index >= 0 && (button == 0 || button == 1)) { ItemStack page = menu.getSlot(index).getItem(); if (!page.isEmpty() && !matchesSearch(page)) return true; - if (renaming) finishRename(); setFocused(null); textInput.setFocused(false); selectedSlot = index; @@ -164,10 +153,7 @@ public final class NotebookScreen extends AbstractContainerScreen @Override public boolean keyPressed(int keyCode, int scanCode, int modifiers) { if (textInput.isFocused()) { - if (renaming && (keyCode == 257 || keyCode == 335)) { - finishRename(); - } else if (keyCode == 256) { - if (renaming) finishRename(); + if (keyCode == 256) { setFocused(null); textInput.setFocused(false); } else { @@ -177,10 +163,6 @@ public final class NotebookScreen extends AbstractContainerScreen // event handles text input. Do not pass them to the container's inventory keys. return true; } - if (!textInput.isFocused() && keyCode == 82 && selectedSlot >= 0) { - toggleRename(); - return true; - } if (!textInput.isFocused() && selectedSlot >= 0 && (keyCode == 263 || keyCode == 262)) { moveSelected(keyCode == 262); return true; @@ -188,12 +170,6 @@ public final class NotebookScreen extends AbstractContainerScreen return super.keyPressed(keyCode, scanCode, modifiers); } - @Override - public void onClose() { - commitRename(); - super.onClose(); - } - private List visiblePages() { List pages = new ArrayList<>(); int firstEmpty = -1; @@ -212,7 +188,7 @@ public final class NotebookScreen extends AbstractContainerScreen } private boolean matchesSearch(ItemStack page) { - return renaming || textInput.getValue().isBlank() + return textInput.getValue().isBlank() || page.getHoverName().getString().toLowerCase(Locale.ROOT) .contains(textInput.getValue().toLowerCase(Locale.ROOT)); } @@ -283,32 +259,6 @@ public final class NotebookScreen extends AbstractContainerScreen } } - private void toggleRename() { - if (renaming) { - finishRename(); - } else if (selectedSlot >= 0 && !menu.getSlot(selectedSlot).getItem().isEmpty()) { - renaming = true; - textInput.setValue(menu.getSlot(selectedSlot).getItem().getHoverName().getString()); - textInput.setHint(Component.translatable("screen.rivencraft.notebook.rename")); - setFocused(textInput); - textInput.setFocused(true); - } - } - - private void finishRename() { - commitRename(); - renaming = false; - textInput.setValue(""); - textInput.setHint(Component.translatable("screen.rivencraft.notebook.search")); - } - - private void commitRename() { - if (renaming && selectedSlot >= 0 && !menu.getSlot(selectedSlot).getItem().isEmpty()) { - PacketDistributor.sendToServer(new RenameNotebookPagePayload( - menu.containerId, selectedSlot, textInput.getValue())); - } - } - private void moveSelected(boolean next) { int target = selectedSlot + (next ? 1 : -1); if (selectedSlot < 0 || target < 0 || target >= NotebookMenu.NOTEBOOK_SLOTS diff --git a/src/main/java/net/dnorberg/rivencraft/gametest/WritingDataGameTests.java b/src/main/java/net/dnorberg/rivencraft/gametest/WritingDataGameTests.java index a2935af..9b36557 100644 --- a/src/main/java/net/dnorberg/rivencraft/gametest/WritingDataGameTests.java +++ b/src/main/java/net/dnorberg/rivencraft/gametest/WritingDataGameTests.java @@ -153,26 +153,27 @@ public final class WritingDataGameTests { } @GameTest(template = "empty") - public static void notebookMenuValidatesInsertionAndPersistsReorderAndRename(GameTestHelper helper) { + public static void notebookMenuValidatesInsertionAndPersistsReorder(GameTestHelper helper) { var player = helper.makeMockServerPlayerInLevel(); ItemStack notebook = new ItemStack(ModItems.NOTEBOOK.get()); player.setItemInHand(InteractionHand.MAIN_HAND, notebook); NotebookMenu menu = new NotebookMenu(7, player.getInventory(), InteractionHand.MAIN_HAND); ItemStack first = PageItem.createSymbolPage(reference("rivencraft:terrain/standard")); + first.set(net.minecraft.core.component.DataComponents.CUSTOM_NAME, + net.minecraft.network.chat.Component.literal("Terrain Base")); ItemStack second = PageItem.createRecoveredPage(reference("example:removed_symbol")); helper.assertFalse(menu.getSlot(0).mayPlace(new ItemStack(Items.DIRT)), "Notebook slots must reject non-Page items"); menu.getSlot(0).set(first); menu.getSlot(1).set(second); - menu.renamePage(0, "Terrain Base"); helper.assertTrue(menu.clickMenuButton(player, NotebookMenu.MOVE_NEXT_BASE), "The server menu must accept a valid adjacent reorder"); NotebookContents saved = notebook.get(ModDataComponents.NOTEBOOK_CONTENTS.get()); helper.assertTrue(saved != null, "Menu changes must persist immediately to the Notebook item"); helper.assertValueEqual(saved.pages().get(1).getHoverName().getString(), "Terrain Base", - "Reordering must preserve the renamed Page stack"); + "Reordering must preserve existing Page item data"); helper.assertValueEqual(PageItem.content(saved.pages().get(0)).kind(), PageContent.Kind.UNRESOLVED_SYMBOL, "Reordering must preserve unresolved pages"); diff --git a/src/main/java/net/dnorberg/rivencraft/menu/NotebookMenu.java b/src/main/java/net/dnorberg/rivencraft/menu/NotebookMenu.java index 80829d6..4030c77 100644 --- a/src/main/java/net/dnorberg/rivencraft/menu/NotebookMenu.java +++ b/src/main/java/net/dnorberg/rivencraft/menu/NotebookMenu.java @@ -6,9 +6,7 @@ import net.dnorberg.rivencraft.registry.ModItems; import net.dnorberg.rivencraft.registry.ModMenus; import net.dnorberg.rivencraft.writing.NotebookContents; import net.minecraft.core.NonNullList; -import net.minecraft.core.component.DataComponents; import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.chat.Component; import net.minecraft.world.Container; import net.minecraft.world.InteractionHand; import net.minecraft.world.SimpleContainer; @@ -118,23 +116,6 @@ public final class NotebookMenu extends AbstractContainerMenu { return true; } - public void renamePage(int slot, String name) { - if (slot < 0 || slot >= NOTEBOOK_SLOTS) { - return; - } - ItemStack page = contents.getItem(slot); - if (page.isEmpty() || !page.is(ModItems.PAGE.get())) { - return; - } - if (name.isBlank()) { - page.remove(DataComponents.CUSTOM_NAME); - } else { - page.set(DataComponents.CUSTOM_NAME, Component.literal(name)); - } - contents.setChanged(); - broadcastChanges(); - } - @Override public void clicked(int slotId, int button, ClickType clickType, Player player) { if (!stillValid(player)) { diff --git a/src/main/java/net/dnorberg/rivencraft/network/ModNetworking.java b/src/main/java/net/dnorberg/rivencraft/network/ModNetworking.java index 69d9f9e..3ea38b5 100644 --- a/src/main/java/net/dnorberg/rivencraft/network/ModNetworking.java +++ b/src/main/java/net/dnorberg/rivencraft/network/ModNetworking.java @@ -12,7 +12,6 @@ import net.dnorberg.rivencraft.client.ClientAgeCelestialAngles; import net.dnorberg.rivencraft.event.AgeCelestialAngleSync; import net.dnorberg.rivencraft.item.DescriptiveBookItem; import net.dnorberg.rivencraft.item.LinkingBookItem; -import net.dnorberg.rivencraft.menu.NotebookMenu; import net.dnorberg.rivencraft.registry.ModDataComponents; import net.dnorberg.rivencraft.registry.ModItems; import net.minecraft.core.component.DataComponents; @@ -50,8 +49,6 @@ public final class ModNetworking { public static void register(RegisterPayloadHandlersEvent event) { PayloadRegistrar registrar = event.registrar("10"); - registrar.playToServer(RenameNotebookPagePayload.TYPE, RenameNotebookPagePayload.STREAM_CODEC, - ModNetworking::renameNotebookPage); registrar.playToServer(RequestDescriptiveBookScreenPayload.TYPE, RequestDescriptiveBookScreenPayload.STREAM_CODEC, ModNetworking::requestDescriptiveBookScreen); registrar.playToClient(OpenDescriptiveBookScreenPayload.TYPE, OpenDescriptiveBookScreenPayload.STREAM_CODEC, @@ -73,16 +70,6 @@ public final class ModNetworking { ClientAgeCelestialAngles::handle); } - private static void renameNotebookPage(RenameNotebookPagePayload payload, IPayloadContext context) { - if (!(context.player() instanceof ServerPlayer player) - || !(player.containerMenu instanceof NotebookMenu menu) - || menu.containerId != payload.containerId() - || payload.name().length() > MAX_BOOK_TITLE_LENGTH) { - return; - } - menu.renamePage(payload.slot(), normalizeTitle(payload.name())); - } - private static void requestDescriptiveBookScreen(RequestDescriptiveBookScreenPayload payload, IPayloadContext context) { if (!(context.player() instanceof ServerPlayer player)) { return; diff --git a/src/main/java/net/dnorberg/rivencraft/network/RenameNotebookPagePayload.java b/src/main/java/net/dnorberg/rivencraft/network/RenameNotebookPagePayload.java deleted file mode 100644 index 09a225c..0000000 --- a/src/main/java/net/dnorberg/rivencraft/network/RenameNotebookPagePayload.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.dnorberg.rivencraft.network; - -import io.netty.buffer.ByteBuf; -import net.dnorberg.rivencraft.Rivencraft; -import net.minecraft.network.codec.ByteBufCodecs; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; - -public record RenameNotebookPagePayload(int containerId, int slot, String name) implements CustomPacketPayload { - public static final Type TYPE = new Type<>( - ResourceLocation.fromNamespaceAndPath(Rivencraft.MOD_ID, "rename_notebook_page")); - public static final StreamCodec STREAM_CODEC = StreamCodec.composite( - ByteBufCodecs.VAR_INT, RenameNotebookPagePayload::containerId, - ByteBufCodecs.VAR_INT, RenameNotebookPagePayload::slot, - ByteBufCodecs.STRING_UTF8, RenameNotebookPagePayload::name, - RenameNotebookPagePayload::new); - - @Override public Type type() { return TYPE; } -} diff --git a/src/main/java/net/dnorberg/rivencraft/registry/ModCreativeTabs.java b/src/main/java/net/dnorberg/rivencraft/registry/ModCreativeTabs.java index 071f725..86eecc6 100644 --- a/src/main/java/net/dnorberg/rivencraft/registry/ModCreativeTabs.java +++ b/src/main/java/net/dnorberg/rivencraft/registry/ModCreativeTabs.java @@ -1,6 +1,7 @@ package net.dnorberg.rivencraft.registry; import net.dnorberg.rivencraft.Rivencraft; +import net.dnorberg.rivencraft.item.PageItem; import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; import net.minecraft.world.item.CreativeModeTab; @@ -19,12 +20,21 @@ public final class ModCreativeTabs { .displayItems((parameters, output) -> { output.accept(ModItems.DESCRIPTIVE_BOOK.get()); output.accept(ModItems.LINKING_BOOK.get()); - output.accept(ModItems.PAGE.get()); output.accept(ModItems.NOTEBOOK.get()); output.accept(ModItems.INK_VIAL.get()); }) .build()); + public static final DeferredHolder PAGES = + CREATIVE_TABS.register("rivencraft_pages", () -> CreativeModeTab.builder() + .title(Component.translatable("itemGroup.rivencraft.pages")) + .icon(PageItem::createLinkPanelPage) + .displayItems((parameters, output) -> { + output.accept(ModItems.PAGE.get()); + output.accept(PageItem.createLinkPanelPage()); + }) + .build()); + private ModCreativeTabs() { } diff --git a/src/main/resources/assets/rivencraft/lang/en_us.json b/src/main/resources/assets/rivencraft/lang/en_us.json index cff6eb9..9335ab2 100644 --- a/src/main/resources/assets/rivencraft/lang/en_us.json +++ b/src/main/resources/assets/rivencraft/lang/en_us.json @@ -18,9 +18,7 @@ "item.rivencraft.ink_vial": "Ink Vial", "item.rivencraft.ink_vial.remaining": "Ink: %s/%s", "item.rivencraft.ink_vial.usage": "Use with a blank Page in the other hand to prepare a Link Panel.", - "screen.rivencraft.notebook.rename": "Rename selected page", "screen.rivencraft.notebook.search": "Search pages", - "screen.rivencraft.notebook.rename_toggle": "Rename selected page (R); use left/right arrows to reorder", "screen.rivencraft.notebook.move_previous": "Move selected page left", "screen.rivencraft.notebook.move_next": "Move selected page right", "message.rivencraft.linking_book.bind_hint": "Sneak-use to bind this book to your current location", @@ -100,5 +98,6 @@ "screen.rivencraft.book.explore": "Explore", "screen.rivencraft.book.exploring": "Exploring", "screen.rivencraft.book.return_from_explore": "Right-click to return", - "itemGroup.rivencraft": "Rivencraft" + "itemGroup.rivencraft": "Rivencraft", + "itemGroup.rivencraft.pages": "Rivencraft Pages" }