Compare commits

..
1 Commits
Author SHA1 Message Date
dnorberg dc5157f973 Fix notebook inventory clicks and ALL button
Build / build (push) Canceled after 0s
2026-09-24 04:23:28 -04:00
4 changed files with 49 additions and 13 deletions

No files matched your search

+1 -1
View File
@@ -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.3.3.2 mod_version=0.3.3.3
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.
@@ -47,12 +47,12 @@ public final class NotebookScreen extends AbstractContainerScreen<NotebookMenu>
Button sortButton = Button.builder(Component.literal("AZ"), button -> {}) Button sortButton = Button.builder(Component.literal("AZ"), button -> {})
.bounds(leftPos, topPos, 18, 18).build(); .bounds(leftPos, topPos, 18, 18).build();
Button allButton = Button.builder(Component.literal("ALL"), button -> {}) Button allButton = Button.builder(Component.literal("ALL"), button -> {})
.bounds(leftPos + 20, topPos, 18, 18).build(); .bounds(leftPos + 20, topPos, 26, 18).build();
sortButton.active = false; sortButton.active = false;
allButton.active = false; allButton.active = false;
addRenderableWidget(sortButton); addRenderableWidget(sortButton);
addRenderableWidget(allButton); addRenderableWidget(allButton);
textInput = new EditBox(font, leftPos + 40, topPos, 94, 18, textInput = new EditBox(font, leftPos + 48, topPos, 86, 18,
Component.translatable("screen.rivencraft.notebook.search")); Component.translatable("screen.rivencraft.notebook.search"));
textInput.setMaxLength(32); textInput.setMaxLength(32);
textInput.setHint(Component.translatable("screen.rivencraft.notebook.search")); textInput.setHint(Component.translatable("screen.rivencraft.notebook.search"));
@@ -22,6 +22,7 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.inventory.ClickType;
import net.neoforged.neoforge.gametest.GameTestHolder; import net.neoforged.neoforge.gametest.GameTestHolder;
import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; import net.neoforged.neoforge.gametest.PrefixGameTestTemplate;
@@ -176,6 +177,29 @@ public final class WritingDataGameTests {
helper.succeed(); helper.succeed();
} }
@GameTest(template = "empty")
public static void notebookMenuSurvivesInventoryStackReplacementAndClicks(GameTestHelper helper) {
var player = helper.makeMockServerPlayerInLevel();
player.setItemInHand(InteractionHand.MAIN_HAND, new ItemStack(ModItems.NOTEBOOK.get()));
NotebookMenu menu = new NotebookMenu(8, player.getInventory(), InteractionHand.MAIN_HAND);
// Slot synchronization may replace the ItemStack object while the Notebook remains held.
player.setItemInHand(InteractionHand.MAIN_HAND, player.getMainHandItem().copy());
helper.assertTrue(menu.stillValid(player),
"Replacing the held stack object must not close an open Notebook menu");
menu.getSlot(0).set(PageItem.createSymbolPage(reference("rivencraft:terrain/standard")));
helper.assertTrue(player.getMainHandItem().has(ModDataComponents.NOTEBOOK_CONTENTS.get()),
"Page edits must persist to the current held Notebook stack");
player.getInventory().setItem(9, new ItemStack(Items.DIRT));
menu.clicked(NotebookMenu.NOTEBOOK_SLOTS, 0, ClickType.PICKUP, player);
helper.assertTrue(menu.getCarried().is(Items.DIRT),
"Clicking a player inventory item must pick it up without closing the Notebook");
helper.assertTrue(menu.stillValid(player),
"Normal inventory clicks must leave the Notebook menu valid");
helper.succeed();
}
private static SymbolReference reference(String id) { private static SymbolReference reference(String id) {
return new SymbolReference(ResourceLocation.parse(id)); return new SymbolReference(ResourceLocation.parse(id));
} }
@@ -26,7 +26,7 @@ public final class NotebookMenu extends AbstractContainerMenu {
private static final int PLAYER_INVENTORY_START = NOTEBOOK_SLOTS; private static final int PLAYER_INVENTORY_START = NOTEBOOK_SLOTS;
private final Inventory playerInventory; private final Inventory playerInventory;
private final InteractionHand hand; private final InteractionHand hand;
private final ItemStack notebook; private final int openedHotbarSlot;
private final NotebookContainer contents; private final NotebookContainer contents;
public NotebookMenu(int containerId, Inventory inventory, RegistryFriendlyByteBuf data) { public NotebookMenu(int containerId, Inventory inventory, RegistryFriendlyByteBuf data) {
@@ -37,8 +37,8 @@ public final class NotebookMenu extends AbstractContainerMenu {
super(ModMenus.NOTEBOOK.get(), containerId); super(ModMenus.NOTEBOOK.get(), containerId);
this.playerInventory = inventory; this.playerInventory = inventory;
this.hand = hand; this.hand = hand;
this.notebook = inventory.player.getItemInHand(hand); this.openedHotbarSlot = inventory.selected;
this.contents = new NotebookContainer(notebook); this.contents = new NotebookContainer(inventory, hand);
for (int row = 0; row < 3; row++) { for (int row = 0; row < 3; row++) {
for (int column = 0; column < 9; column++) { for (int column = 0; column < 9; column++) {
@@ -58,14 +58,16 @@ public final class NotebookMenu extends AbstractContainerMenu {
} }
private Slot playerSlot(int inventoryIndex, int x, int y) { private Slot playerSlot(int inventoryIndex, int x, int y) {
boolean locked = hand == InteractionHand.MAIN_HAND && inventoryIndex == playerInventory.selected; boolean locked = hand == InteractionHand.MAIN_HAND && inventoryIndex == openedHotbarSlot;
return locked ? new LockedSlot(playerInventory, inventoryIndex, x, y) return locked ? new LockedSlot(playerInventory, inventoryIndex, x, y)
: new Slot(playerInventory, inventoryIndex, x, y); : new Slot(playerInventory, inventoryIndex, x, y);
} }
@Override @Override
public boolean stillValid(Player player) { public boolean stillValid(Player player) {
return player.isAlive() && player.getItemInHand(hand) == notebook && notebook.is(ModItems.NOTEBOOK.get()); return player.isAlive()
&& (hand == InteractionHand.OFF_HAND || player.getInventory().selected == openedHotbarSlot)
&& player.getItemInHand(hand).is(ModItems.NOTEBOOK.get());
} }
@Override @Override
@@ -135,10 +137,16 @@ public final class NotebookMenu extends AbstractContainerMenu {
@Override @Override
public void clicked(int slotId, int button, ClickType clickType, Player player) { public void clicked(int slotId, int button, ClickType clickType, Player player) {
super.clicked(slotId, button, clickType, player);
if (!stillValid(player)) { if (!stillValid(player)) {
player.closeContainer(); player.closeContainer();
return;
} }
if (clickType == ClickType.SWAP
&& (button == openedHotbarSlot && hand == InteractionHand.MAIN_HAND
|| button == 40 && hand == InteractionHand.OFF_HAND)) {
return;
}
super.clicked(slotId, button, clickType, player);
} }
private static final class PageSlot extends Slot { private static final class PageSlot extends Slot {
@@ -160,12 +168,15 @@ public final class NotebookMenu extends AbstractContainerMenu {
} }
private static final class NotebookContainer extends SimpleContainer { private static final class NotebookContainer extends SimpleContainer {
private final ItemStack notebook; private final Inventory inventory;
private final InteractionHand hand;
private boolean loading; private boolean loading;
private NotebookContainer(ItemStack notebook) { private NotebookContainer(Inventory inventory, InteractionHand hand) {
super(NOTEBOOK_SLOTS); super(NOTEBOOK_SLOTS);
this.notebook = notebook; this.inventory = inventory;
this.hand = hand;
ItemStack notebook = inventory.player.getItemInHand(hand);
loading = true; loading = true;
List<ItemStack> saved = notebook.getOrDefault( List<ItemStack> saved = notebook.getOrDefault(
ModDataComponents.NOTEBOOK_CONTENTS.get(), NotebookContents.EMPTY).pages(); ModDataComponents.NOTEBOOK_CONTENTS.get(), NotebookContents.EMPTY).pages();
@@ -187,7 +198,8 @@ public final class NotebookMenu extends AbstractContainerMenu {
@Override @Override
public void setChanged() { public void setChanged() {
super.setChanged(); super.setChanged();
if (loading || notebook.isEmpty()) { ItemStack notebook = inventory.player.getItemInHand(hand);
if (loading || !notebook.is(ModItems.NOTEBOOK.get())) {
return; return;
} }
NonNullList<ItemStack> saved = NonNullList.withSize(NOTEBOOK_SLOTS, ItemStack.EMPTY); NonNullList<ItemStack> saved = NonNullList.withSize(NOTEBOOK_SLOTS, ItemStack.EMPTY);