Compare commits

..
1 Commits
Author SHA1 Message Date
dnorberg 385741027a Show Writing Desk page previews like Legacy
Build / build (push) Canceled after 0s
2026-09-24 05:17:31 -04:00
5 changed files with 106 additions and 9 deletions

No files matched your search

+2
View File
@@ -25,6 +25,8 @@ Its four collection tabs, ink/source/page work slots, and inventory persist
through world saves; breaking it drops stored contents. The desk screen is a through world saves; breaking it drops stored contents. The desk screen is a
functional foundation styled after Legacy's left tabs, central writing surface, functional foundation styled after Legacy's left tabs, central writing surface,
and right inventory. Transcription controls are not implemented yet. and right inventory. Transcription controls are not implemented yet.
Selecting a stored page on the desk surface shows its Legacy-proportioned
portrait preview and name above the player inventory.
## Linking Book ## Linking Book
+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.5.0 mod_version=0.3.5.1
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.
@@ -271,7 +271,7 @@ public final class NotebookScreen extends AbstractContainerScreen<NotebookMenu>
} }
} }
private static ResourceLocation symbolTexture(ItemStack page) { static ResourceLocation symbolTexture(ItemStack page) {
var content = PageItem.content(page); var content = PageItem.content(page);
if (content.kind() == net.dnorberg.rivencraft.writing.PageContent.Kind.UNRESOLVED_SYMBOL) { if (content.kind() == net.dnorberg.rivencraft.writing.PageContent.Kind.UNRESOLVED_SYMBOL) {
return UNRESOLVED_SYMBOL; return UNRESOLVED_SYMBOL;
@@ -1,13 +1,27 @@
package net.dnorberg.rivencraft.client.screen; package net.dnorberg.rivencraft.client.screen;
import java.util.List;
import net.dnorberg.rivencraft.Rivencraft;
import net.dnorberg.rivencraft.item.PageItem;
import net.dnorberg.rivencraft.menu.WritingDeskMenu; import net.dnorberg.rivencraft.menu.WritingDeskMenu;
import net.dnorberg.rivencraft.registry.ModDataComponents;
import net.dnorberg.rivencraft.registry.ModItems;
import net.dnorberg.rivencraft.writing.NotebookContents;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.item.ItemStack;
/** Functional storage surface; full Legacy transcription controls are a later Milestone 4 slice. */ /** Functional storage surface; full Legacy transcription controls are a later Milestone 4 slice. */
public final class WritingDeskScreen extends AbstractContainerScreen<WritingDeskMenu> { public final class WritingDeskScreen extends AbstractContainerScreen<WritingDeskMenu> {
private static final ResourceLocation PAGE_ATLAS = ResourceLocation.fromNamespaceAndPath(
Rivencraft.MOD_ID, "textures/gui/notebook_pages.png");
private int lastCollection = -1;
private int selectedPage;
private int scrollRows;
public WritingDeskScreen(WritingDeskMenu menu, Inventory inventory, Component title) { public WritingDeskScreen(WritingDeskMenu menu, Inventory inventory, Component title) {
super(menu, inventory, title); super(menu, inventory, title);
imageWidth = 398; imageWidth = 398;
@@ -29,10 +43,10 @@ public final class WritingDeskScreen extends AbstractContainerScreen<WritingDesk
i == menu.activeCollection() ? 0xFF7777B6 : 0xFF999999); i == menu.activeCollection() ? 0xFF7777B6 : 0xFF999999);
slotFrame(graphics, 12, 20 + i * 37); slotFrame(graphics, 12, 20 + i * 37);
} }
slotFrame(graphics, 370, 20);
slotFrame(graphics, 228, 20); slotFrame(graphics, 228, 20);
slotFrame(graphics, 266, 20); slotFrame(graphics, 228, 57);
slotFrame(graphics, 304, 20); slotFrame(graphics, 370, 57);
slotFrame(graphics, 342, 20);
for (int row = 0; row < 3; row++) { for (int row = 0; row < 3; row++) {
for (int column = 0; column < 9; column++) slotFrame(graphics, 224 + column * 18, 91 + row * 18); for (int column = 0; column < 9; column++) slotFrame(graphics, 224 + column * 18, 91 + row * 18);
} }
@@ -46,12 +60,83 @@ public final class WritingDeskScreen extends AbstractContainerScreen<WritingDesk
leftPos + x + 16, topPos + y + 16, 0xFF858585); leftPos + x + 16, topPos + y + 16, 0xFF858585);
} }
@Override protected void renderLabels(GuiGraphics graphics, int mouseX, int mouseY) {
graphics.drawString(font, playerInventoryTitle, inventoryLabelX, inventoryLabelY, 0x404040, false);
}
@Override public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) { @Override public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
super.render(graphics, mouseX, mouseY, partialTick); super.render(graphics, mouseX, mouseY, partialTick);
renderCollection(graphics);
renderTooltip(graphics, mouseX, mouseY); renderTooltip(graphics, mouseX, mouseY);
} }
private List<ItemStack> pages() {
ItemStack collection = menu.getSlot(menu.activeCollection()).getItem();
if (collection.is(ModItems.PAGE.get())) return List.of(collection);
if (collection.is(ModItems.NOTEBOOK.get())) {
return collection.getOrDefault(ModDataComponents.NOTEBOOK_CONTENTS.get(), NotebookContents.EMPTY).pages();
}
return List.of();
}
private void renderCollection(GuiGraphics graphics) {
List<ItemStack> pages = pages();
if (lastCollection != menu.activeCollection()) {
lastCollection = menu.activeCollection();
scrollRows = 0;
selectedPage = 0;
}
int last = -1;
for (int i = 0; i < pages.size(); i++) if (!pages.get(i).isEmpty()) last = i;
for (int i = scrollRows * 5; i <= last && i < scrollRows * 5 + 15; i++) {
int column = i % 5;
int row = i / 5 - scrollRows;
ItemStack page = pages.get(i);
int x = leftPos + 48 + column * 31;
int y = topPos + 18 + row * 41;
drawPage(graphics, page, x, y);
if (page.isEmpty()) graphics.fill(x, y, x + 30, y + 40, 0xB8000000);
if (i == selectedPage && !page.isEmpty()) graphics.renderOutline(x, y, 30, 40, 0xFFFFD061);
}
if (selectedPage >= pages.size() || pages.get(selectedPage).isEmpty()) return;
ItemStack selected = pages.get(selectedPage);
graphics.pose().pushPose();
graphics.pose().translate(leftPos + 294, topPos + 12, 0);
graphics.pose().scale(1.35F, 1.35F, 1.0F);
drawPage(graphics, selected, 0, 0);
graphics.pose().popPose();
String title = font.plainSubstrByWidth(selected.getHoverName().getString(), 112);
graphics.fill(leftPos + 251, topPos + 64, leftPos + 365, topPos + 77, 0xFF202020);
graphics.drawString(font, title, leftPos + 254, topPos + 67, 0xFFE0E0E0, false);
}
private void drawPage(GuiGraphics graphics, ItemStack page, int x, int y) {
graphics.blit(PAGE_ATLAS, x, y, 30, 40, 156, 0, 30, 40, 256, 256);
if (page.isEmpty()) return;
switch (PageItem.content(page).kind()) {
case BLANK -> { }
case LINK_PANEL -> graphics.fill(x + 5, y + 6, x + 25, y + 20, 0xFF000000);
case SYMBOL, UNRESOLVED_SYMBOL -> graphics.blit(NotebookScreen.symbolTexture(page), x + 1, y + 6,
28, 28, 16, 16, 96, 96, 128, 128);
}
}
@Override public boolean mouseClicked(double mouseX, double mouseY, int button) { @Override public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (button == 0) {
int x = (int) mouseX - leftPos - 48;
int y = (int) mouseY - topPos - 18;
if (x >= 0 && x < 155 && y >= 0 && y < 123) {
int column = x / 31;
int row = y / 41;
int index = (row + scrollRows) * 5 + column;
List<ItemStack> pages = pages();
if (x % 31 < 30 && y % 41 < 40 && index < pages.size()
&& !pages.get(index).isEmpty()) {
selectedPage = index;
}
return true;
}
}
if (button == 0 && mouseX >= leftPos + 29 && mouseX < leftPos + 40) { if (button == 0 && mouseX >= leftPos + 29 && mouseX < leftPos + 40) {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
int top = topPos + 16 + i * 37; int top = topPos + 16 + i * 37;
@@ -65,4 +150,14 @@ public final class WritingDeskScreen extends AbstractContainerScreen<WritingDesk
} }
return super.mouseClicked(mouseX, mouseY, button); return super.mouseClicked(mouseX, mouseY, button);
} }
@Override public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) {
if (mouseX >= leftPos + 48 && mouseX < leftPos + 203
&& mouseY >= topPos + 18 && mouseY < topPos + 141) {
int rows = (pages().size() + 4) / 5;
scrollRows = Math.clamp(scrollRows - (int) Math.signum(scrollY), 0, Math.max(0, rows - 3));
return true;
}
return super.mouseScrolled(mouseX, mouseY, scrollX, scrollY);
}
} }
@@ -36,10 +36,10 @@ public final class WritingDeskMenu extends AbstractContainerMenu {
for (int i = 0; i < WritingDeskBlockEntity.COLLECTIONS; i++) { for (int i = 0; i < WritingDeskBlockEntity.COLLECTIONS; i++) {
addSlot(new DeskSlot(desk, i, 12, 20 + i * 37, 1)); addSlot(new DeskSlot(desk, i, 12, 20 + i * 37, 1));
} }
addSlot(new DeskSlot(desk, WritingDeskBlockEntity.INK, 228, 20, 1)); addSlot(new DeskSlot(desk, WritingDeskBlockEntity.INK, 370, 20, 1));
addSlot(new DeskSlot(desk, WritingDeskBlockEntity.SOURCE, 266, 20, 1)); addSlot(new DeskSlot(desk, WritingDeskBlockEntity.SOURCE, 228, 20, 1));
addSlot(new DeskSlot(desk, WritingDeskBlockEntity.PAPER, 304, 20, 64)); addSlot(new DeskSlot(desk, WritingDeskBlockEntity.PAPER, 228, 57, 64));
addSlot(new DeskSlot(desk, WritingDeskBlockEntity.OUTPUT, 342, 20, 64)); addSlot(new DeskSlot(desk, WritingDeskBlockEntity.OUTPUT, 370, 57, 64));
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++) {
addSlot(new Slot(inventory, column + row * 9 + 9, 224 + column * 18, 91 + row * 18)); addSlot(new Slot(inventory, column + row * 9 + 9, 224 + column * 18, 91 + row * 18));