diff --git a/CHANGELOG.md b/CHANGELOG.md index 04a236e5..9b0b3591 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,55 @@ way to 1.0.0; see [docs/ROADMAP.md](docs/ROADMAP.md). ## [Unreleased] +## [1.1.0] - 2026-11-07 + +The first full release since 1.0.0, on Forge, NeoForge and Fabric for Minecraft 26.3, 26.2, 26.1, 1.21.11, +1.21.5, 1.21.1 and 1.20.6: 21 jars, one per loader and version. The details of everything below are in the +beta sections that follow. Players and servers need the same version. The network protocol is the same as +in 1.1.0-beta.8 and later (11). + +### Before you update + +Back up your world. Scripted clients ran on every loader and version during development and dedicated +servers start on all of them, but only the Forge 26.3 jar has been started from a launcher profile, and +nobody has played the released jars yet. Testing happens on this release, and fixes go into 1.1.1. Please +report what you find on [GitHub](https://github.com/JnH-Projects/MCHeli-Rework-Forge/issues) with your +`logs/latest.log`. + +### Installing + +This jar contains only the mod's code. The vehicles, models, textures and sounds are EMB4's original +MCHeli content, which you download yourself: + +1. Install Forge, NeoForge or Fabric for your Minecraft version. On Fabric, also install Fabric API. +2. Put `mcheli---1.1.0.jar` in the `mods` folder. +3. Download `MC1.7.10_mcheli_1.0.3.zip` from the + [MCHeli CurseForge page, Files tab](https://www.curseforge.com/minecraft/mc-mods/mcheli-minecraft-helicopter-mod/files). +4. Create a folder called `mcheli` next to `mods` and put the zip in it. Do not unzip it. +5. Start the game. The first start converts the zip, which takes a few seconds. + +### Added since 1.0.0 + +- NeoForge and Fabric next to Forge, and six more Minecraft versions next to 26.3. +- Vehicle workshop: build a vehicle in game from a Blockbench or Blender model, with its own textures and + sounds, and send it to a server for its operators to approve. +- Content packs, sent to players when they join a server. +- Fuel, the vehicle screen, cargo and supply vehicles. +- The rest of the original's equipment, including the thermal view, UAV stations, the drafting table and + the team manager. +- Night glow on tracers, rocket motors, flares and explosions, and wrecks that keep burning for 30 seconds. +- Server settings in `serverconfig/mcheli-server.toml`, and `/mcheli` to list, give and reload vehicles. + +### Changed + +- 1.20.2 and 1.19.4 are not part of this release. + +### Fixed + +- Drafting table: the recipe position ("1 / 35") ran into the top row of the inventory and the "Inventory" + title crossed the panel's border, on every Minecraft version. The position now sits between narrower `<<` + and `>>` buttons, and the title sits above the panel. + ## [1.1.0-beta.9] - 2026-11-07 Phase 13 of the road to 1.1.0: every loader on every supported version. This beta ships 21 jars, one per @@ -760,6 +809,7 @@ Phase 1: foundation and flyable helicopters. - Free look moved from Left Ctrl to Left Alt, because Left Ctrl is now the vanilla sprint key. - Roll damping runs per tick instead of per frame, so handling no longer depends on frame rate. +[1.1.0]: https://github.com/JnH-Projects/MCHeli-Rework-Forge/releases/tag/v1.1.0 [1.1.0-beta.9]: https://github.com/JnH-Projects/MCHeli-Rework-Forge/releases/tag/v1.1.0-beta.9 [1.1.0-beta.8.1]: https://github.com/JnH-Projects/MCHeli-Rework-Forge/releases/tag/v1.1.0-beta.8.1 [1.1.0-beta.8]: https://github.com/JnH-Projects/MCHeli-Rework-Forge/releases/tag/v1.1.0-beta.8 diff --git a/README.md b/README.md index ca4e18c0..01c5fb40 100644 --- a/README.md +++ b/README.md @@ -9,14 +9,15 @@ MCHeli Rework is a ground-up port of MCHeli 1.0.3, a mod that stopped at Minecra system is rewritten for the modern game, while the original vehicle definitions, models, textures and sounds load unchanged. -> **Status:** on the way to 1.1.0, now at phase 13 (`1.1.0-beta.9`). Every helicopter, plane, +> **Status:** `1.1.0` is the current release. Every helicopter, plane, > tank, car and ground vehicle can be placed, crewed and driven with the original handling, all > 229 weapons fire, and the scripted HUDs, fuel, the vehicle screen and all of the original's > equipment are in, down to UAV stations, the drafting table and the team manager. The vehicle > workshop builds new vehicles in game from a Blockbench or Blender model, with their own textures -> and sounds, and sends them to a server for its operators to approve. From `1.1.0-beta.9` on, -> every jar ships: Forge, NeoForge and Fabric for every version from 1.20.6 to 26.3 (see -> [supported versions](docs/ROADMAP.md#supported-versions)). See the [roadmap](docs/ROADMAP.md). +> and sounds, and sends them to a server for its operators to approve. Every jar ships: Forge, +> NeoForge and Fabric for every version from 1.20.6 to 26.3 (see +> [supported versions](docs/ROADMAP.md#supported-versions)). Testers are playing these jars for the +> first time on this release, and fixes go into 1.1.1. See the [roadmap](docs/ROADMAP.md). ## Showcase video @@ -63,7 +64,8 @@ mod does not ship it: on first start it converts the player's own copy of the or to the modern resource layout. This repository holds none of it either; the unit tests import the same zip. -The rework is by **JayMar921** ([JnH Projects](https://github.com/JnH-Projects)). +The rework is by **JayMar921** ([JnH Projects](https://github.com/JnH-Projects)). More of their +projects and plugins are at [jhprojects.dev](https://www.jhprojects.dev). ## Licensing note diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index d86edf6d..976712d7 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -1,7 +1,7 @@ # Architecture This document explains how MCHeli Rework is organized and why. It reflects the code as of -`1.1.0-beta.3`. +`1.1.0`. ## Goals diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 821a9eb7..0bf8578b 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -2,7 +2,7 @@ The original mod is about 60,000 lines of 1.7.10 code. Nearly all of it touches APIs that no longer exist (immediate mode OpenGL, numeric ids, the old network and event systems), so the port -happened in four phases toward 1.0.0, and 1.1.0 continues with six more. Each phase ends with a +happened in four phases toward 1.0.0, and 1.1.0 continued with nine more. Each phase ends with a tagged pre-release that installs and runs on its own. | Phase | Version | Theme | State | @@ -12,8 +12,9 @@ tagged pre-release that installs and runs on its own. | 3 | `1.0.0-alpha.3` | Weapons and combat | Implemented, in-game test in progress | | 4 | `1.0.0-beta.1` | HUD and polish | Done | | | `1.0.0` | Release: code-only jar | Released | -| 5-13 | `1.1.0-beta.1` to `beta.9` | Content packs, NeoForge and Fabric, equipment, workshop, every release version from 1.20.6 to 26.3 ([plan](#road-to-110)) | In progress | -| | `1.1.0` | Release on CurseForge | Planned | +| 5-13 | `1.1.0-beta.1` to `beta.9` | Content packs, NeoForge and Fabric, equipment, workshop, every release version from 1.20.6 to 26.3 ([plan](#road-to-110)) | Released | +| | `1.1.0` | Release on CurseForge | Released | +| | `1.1.1` | Fixes for what testers find on 1.1.0 ([list](#111-after-testing)) | Planned | ## Phase 1: foundation and flyable helicopters @@ -105,7 +106,7 @@ split into nine phases, each ending in a beta. |-------|--------------|-------------|------------| | `1.1.0-beta.N` | GitHub pre-release | Mirrored, GitHub pre-release | Not uploaded | | `1.1.0-rc.N` (if needed) | GitHub pre-release | Mirrored, GitHub pre-release | Not uploaded | -| `1.1.0` | GitHub release | Mirrored, GitHub release | Uploaded, one file per Minecraft version | +| `1.1.0` | GitHub release | Mirrored, GitHub release | Uploaded, one file per Minecraft version and loader | Every beta goes through the usual flow: set `mod_version`, move the changelog section, merge, tag `v1.1.0-beta.N` in the private repo, mirror the commits to the public repo and tag the same @@ -141,7 +142,7 @@ Rules that hold for every beta: | 12 | `1.1.0-beta.8` | Workshop: textures, sounds and sharing (Forge 26.3 only) | Released | | | `1.1.0-beta.8.1` | Hotfix: the files missing from the released jars | Released | | 13 | `1.1.0-beta.9` | Every loader on every supported version, 1.20.6 to 26.3 | Released | -| | `1.1.0` | Release on CurseForge | Planned | +| | `1.1.0` | Release on CurseForge | Released | The order is deliberate. The registry and the source split come first because everything else sits on them. Content packs come before the workshop, since the workshop's output is a pack. @@ -325,15 +326,22 @@ to the 1.1.0 release. Only the Forge 26.3 jar has been started from a launcher p ## 1.1.0 release -No new features after beta.9; a `1.1.0-rc.N` follows only if beta.9 testing finds problems. +No new features after beta.9. Hands-on testing moved from before this release to after it: testers play +the released jars, and what they find goes into 1.1.1 instead of a `1.1.0-rc.N`. + +- [x] Drafting table labels no longer run into the inventory +- [x] Tag `v1.1.0` in both repositories; upload one CurseForge file per Minecraft version and loader, with + the player-facing changelog from `docs/CURSEFORGE.md` + +## 1.1.1: after testing + +Fixes for what testers find on 1.1.0, and these checks, which no one has done yet: - [ ] The phase 7 smoke tests for every jar ([TESTING.md](TESTING.md#smoke-test-every-jar)), each from a launcher profile, with a real flight, weapons, sound by ear and a pack download from a server - [ ] Every phase checklist done on every supported Minecraft version - [ ] A 1.0.0 world and the beta worlds load with their vehicles and items intact - [ ] A pack made in the workshop on one version loads on every other supported version -- [ ] Tag `v1.1.0` in both repositories; upload one CurseForge file per Minecraft version and loader, with - the player-facing changelog from `docs/CURSEFORGE.md` ## Open decisions diff --git a/gradle.properties b/gradle.properties index 60d02c3c..af5d18e2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ net.minecraftforge.gradle.merge-source-sets=true mod_id=mcheli mod_name=MCHeli Rework mod_group=com.jnhprojects.mcheli -mod_version=1.1.0-beta.9 +mod_version=1.1.0 mod_authors=JayMar921 (rework), EMB4 (original author), Fureniku (CurseForge maintainer) mod_license=MCHeli Rework Licence 1.0 (see LICENSE) diff --git a/minecraft-1.20.6/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java b/minecraft-1.20.6/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java index 52af9514..1a6d6174 100644 --- a/minecraft-1.20.6/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java +++ b/minecraft-1.20.6/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java @@ -71,7 +71,7 @@ public DraftingTableScreen(DraftingTableMenu menu, Inventory inventory, Componen imageWidth = 400; imageHeight = 240; inventoryLabelX = 30; - inventoryLabelY = 130; + inventoryLabelY = 122; } @Override @@ -85,8 +85,8 @@ protected void init() { } create = addRenderableWidget(Button.builder(Component.translatable("gui.mcheli.drafting_table.create"), b -> create()) .bounds(leftPos + 120, topPos + 89, 50, 20).build()); - previous = addRenderableWidget(Button.builder(Component.literal("<<"), b -> step(-1)).bounds(leftPos + 120, topPos + 111, 36, 20).build()); - next = addRenderableWidget(Button.builder(Component.literal(">>"), b -> step(1)).bounds(leftPos + 155, topPos + 111, 35, 20).build()); + previous = addRenderableWidget(Button.builder(Component.literal("<<"), b -> step(-1)).bounds(leftPos + 120, topPos + 111, 16, 20).build()); + next = addRenderableWidget(Button.builder(Component.literal(">>"), b -> step(1)).bounds(leftPos + 180, topPos + 111, 16, 20).build()); previousPage = addRenderableWidget(Button.builder(Component.translatable("gui.mcheli.drafting_table.previous_page"), b -> turnPage(-1)) .bounds(leftPos + 210, topPos + 210, 60, 20).build()); nextPage = addRenderableWidget(Button.builder(Component.translatable("gui.mcheli.drafting_table.next_page"), b -> turnPage(1)) @@ -268,7 +268,8 @@ protected void renderLabels(GuiGraphics graphics, int mouseX, int mouseY) { } ItemStack result = result(); graphics.drawString(font, font.plainSubstrByWidth(result.getHoverName().getString(), 85), 120, 20, WHITE, true); - graphics.drawString(font, (index + 1) + " / " + lists.get(list).size(), 120, 134, TEXT, false); + String position = (index + 1) + " / " + lists.get(list).size(); + graphics.drawString(font, position, 158 - font.width(position) / 2, 117, TEXT, false); ingredients(graphics, entry.value(), mouseX, mouseY); graphics.renderItem(result, 178, 52); if (pageCount == 0) { diff --git a/minecraft-1.21.1/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java b/minecraft-1.21.1/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java index be430bf1..5096a20f 100644 --- a/minecraft-1.21.1/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java +++ b/minecraft-1.21.1/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java @@ -71,7 +71,7 @@ public DraftingTableScreen(DraftingTableMenu menu, Inventory inventory, Componen imageWidth = 400; imageHeight = 240; inventoryLabelX = 30; - inventoryLabelY = 130; + inventoryLabelY = 122; } @Override @@ -85,8 +85,8 @@ protected void init() { } create = addRenderableWidget(Button.builder(Component.translatable("gui.mcheli.drafting_table.create"), b -> create()) .bounds(leftPos + 120, topPos + 89, 50, 20).build()); - previous = addRenderableWidget(Button.builder(Component.literal("<<"), b -> step(-1)).bounds(leftPos + 120, topPos + 111, 36, 20).build()); - next = addRenderableWidget(Button.builder(Component.literal(">>"), b -> step(1)).bounds(leftPos + 155, topPos + 111, 35, 20).build()); + previous = addRenderableWidget(Button.builder(Component.literal("<<"), b -> step(-1)).bounds(leftPos + 120, topPos + 111, 16, 20).build()); + next = addRenderableWidget(Button.builder(Component.literal(">>"), b -> step(1)).bounds(leftPos + 180, topPos + 111, 16, 20).build()); previousPage = addRenderableWidget(Button.builder(Component.translatable("gui.mcheli.drafting_table.previous_page"), b -> turnPage(-1)) .bounds(leftPos + 210, topPos + 210, 60, 20).build()); nextPage = addRenderableWidget(Button.builder(Component.translatable("gui.mcheli.drafting_table.next_page"), b -> turnPage(1)) @@ -268,7 +268,8 @@ protected void renderLabels(GuiGraphics graphics, int mouseX, int mouseY) { } ItemStack result = result(); graphics.drawString(font, font.plainSubstrByWidth(result.getHoverName().getString(), 85), 120, 20, WHITE, true); - graphics.drawString(font, (index + 1) + " / " + lists.get(list).size(), 120, 134, TEXT, false); + String position = (index + 1) + " / " + lists.get(list).size(); + graphics.drawString(font, position, 158 - font.width(position) / 2, 117, TEXT, false); ingredients(graphics, entry.value(), mouseX, mouseY); graphics.renderItem(result, 178, 52); if (pageCount == 0) { diff --git a/minecraft-1.21.11/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java b/minecraft-1.21.11/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java index 1966cc4a..ee7c54c1 100644 --- a/minecraft-1.21.11/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java +++ b/minecraft-1.21.11/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java @@ -75,7 +75,7 @@ public DraftingTableScreen(DraftingTableMenu menu, Inventory inventory, Componen imageWidth = 400; imageHeight = 240; inventoryLabelX = 30; - inventoryLabelY = 130; + inventoryLabelY = 122; } @Override @@ -89,8 +89,8 @@ protected void init() { } create = addRenderableWidget(Button.builder(Component.translatable("gui.mcheli.drafting_table.create"), b -> create()) .bounds(leftPos + 120, topPos + 89, 50, 20).build()); - previous = addRenderableWidget(Button.builder(Component.literal("<<"), b -> step(-1)).bounds(leftPos + 120, topPos + 111, 36, 20).build()); - next = addRenderableWidget(Button.builder(Component.literal(">>"), b -> step(1)).bounds(leftPos + 155, topPos + 111, 35, 20).build()); + previous = addRenderableWidget(Button.builder(Component.literal("<<"), b -> step(-1)).bounds(leftPos + 120, topPos + 111, 16, 20).build()); + next = addRenderableWidget(Button.builder(Component.literal(">>"), b -> step(1)).bounds(leftPos + 180, topPos + 111, 16, 20).build()); previousPage = addRenderableWidget(Button.builder(Component.translatable("gui.mcheli.drafting_table.previous_page"), b -> turnPage(-1)) .bounds(leftPos + 210, topPos + 210, 60, 20).build()); nextPage = addRenderableWidget(Button.builder(Component.translatable("gui.mcheli.drafting_table.next_page"), b -> turnPage(1)) @@ -264,7 +264,8 @@ protected void renderLabels(GuiGraphics graphics, int mouseX, int mouseY) { } ItemStack result = result(); graphics.drawString(font, font.plainSubstrByWidth(result.getHoverName().getString(), 85), 120, 20, WHITE, true); - graphics.drawString(font, (index + 1) + " / " + lists.get(list).size(), 120, 134, TEXT, false); + String position = (index + 1) + " / " + lists.get(list).size(); + graphics.drawString(font, position, 158 - font.width(position) / 2, 117, TEXT, false); ingredients(graphics, entry.display(), mouseX, mouseY); graphics.renderItem(result, 178, 52); if (pageCount == 0) { diff --git a/minecraft-1.21.5/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java b/minecraft-1.21.5/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java index a88e5213..83639a6a 100644 --- a/minecraft-1.21.5/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java +++ b/minecraft-1.21.5/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java @@ -76,7 +76,7 @@ public DraftingTableScreen(DraftingTableMenu menu, Inventory inventory, Componen imageWidth = 400; imageHeight = 240; inventoryLabelX = 30; - inventoryLabelY = 130; + inventoryLabelY = 122; } @Override @@ -90,8 +90,8 @@ protected void init() { } create = addRenderableWidget(Button.builder(Component.translatable("gui.mcheli.drafting_table.create"), b -> create()) .bounds(leftPos + 120, topPos + 89, 50, 20).build()); - previous = addRenderableWidget(Button.builder(Component.literal("<<"), b -> step(-1)).bounds(leftPos + 120, topPos + 111, 36, 20).build()); - next = addRenderableWidget(Button.builder(Component.literal(">>"), b -> step(1)).bounds(leftPos + 155, topPos + 111, 35, 20).build()); + previous = addRenderableWidget(Button.builder(Component.literal("<<"), b -> step(-1)).bounds(leftPos + 120, topPos + 111, 16, 20).build()); + next = addRenderableWidget(Button.builder(Component.literal(">>"), b -> step(1)).bounds(leftPos + 180, topPos + 111, 16, 20).build()); previousPage = addRenderableWidget(Button.builder(Component.translatable("gui.mcheli.drafting_table.previous_page"), b -> turnPage(-1)) .bounds(leftPos + 210, topPos + 210, 60, 20).build()); nextPage = addRenderableWidget(Button.builder(Component.translatable("gui.mcheli.drafting_table.next_page"), b -> turnPage(1)) @@ -265,7 +265,8 @@ protected void renderLabels(GuiGraphics graphics, int mouseX, int mouseY) { } ItemStack result = result(); graphics.drawString(font, font.plainSubstrByWidth(result.getHoverName().getString(), 85), 120, 20, WHITE, true); - graphics.drawString(font, (index + 1) + " / " + lists.get(list).size(), 120, 134, TEXT, false); + String position = (index + 1) + " / " + lists.get(list).size(); + graphics.drawString(font, position, 158 - font.width(position) / 2, 117, TEXT, false); ingredients(graphics, entry.display(), mouseX, mouseY); graphics.renderItem(result, 178, 52); if (pageCount == 0) { diff --git a/minecraft-26.1/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java b/minecraft-26.1/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java index e70d6bd0..9eaace95 100644 --- a/minecraft-26.1/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java +++ b/minecraft-26.1/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java @@ -73,7 +73,7 @@ public class DraftingTableScreen extends AbstractContainerScreen create()) .bounds(leftPos + 120, topPos + 89, 50, 20).build()); - previous = addRenderableWidget(Button.builder(Component.literal("<<"), b -> step(-1)).bounds(leftPos + 120, topPos + 111, 36, 20).build()); - next = addRenderableWidget(Button.builder(Component.literal(">>"), b -> step(1)).bounds(leftPos + 155, topPos + 111, 35, 20).build()); + previous = addRenderableWidget(Button.builder(Component.literal("<<"), b -> step(-1)).bounds(leftPos + 120, topPos + 111, 16, 20).build()); + next = addRenderableWidget(Button.builder(Component.literal(">>"), b -> step(1)).bounds(leftPos + 180, topPos + 111, 16, 20).build()); previousPage = addRenderableWidget(Button.builder(Component.translatable("gui.mcheli.drafting_table.previous_page"), b -> turnPage(-1)) .bounds(leftPos + 210, topPos + 210, 60, 20).build()); nextPage = addRenderableWidget(Button.builder(Component.translatable("gui.mcheli.drafting_table.next_page"), b -> turnPage(1)) @@ -263,7 +263,8 @@ protected void extractLabels(GuiGraphicsExtractor graphics, int mouseX, int mous } ItemStack result = result(); graphics.text(font, font.plainSubstrByWidth(result.getHoverName().getString(), 85), 120, 20, WHITE, true); - graphics.text(font, (index + 1) + " / " + lists.get(list).size(), 120, 134, TEXT, false); + String position = (index + 1) + " / " + lists.get(list).size(); + graphics.text(font, position, 158 - font.width(position) / 2, 117, TEXT, false); ingredients(graphics, entry.display(), mouseX, mouseY); graphics.item(result, 178, 52); if (pageCount == 0) { diff --git a/minecraft-26.2/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java b/minecraft-26.2/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java index ec38e26d..0328545a 100644 --- a/minecraft-26.2/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java +++ b/minecraft-26.2/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java @@ -73,7 +73,7 @@ public class DraftingTableScreen extends AbstractContainerScreen create()) .bounds(leftPos + 120, topPos + 89, 50, 20).build()); - previous = addRenderableWidget(Button.builder(Component.literal("<<"), b -> step(-1)).bounds(leftPos + 120, topPos + 111, 36, 20).build()); - next = addRenderableWidget(Button.builder(Component.literal(">>"), b -> step(1)).bounds(leftPos + 155, topPos + 111, 35, 20).build()); + previous = addRenderableWidget(Button.builder(Component.literal("<<"), b -> step(-1)).bounds(leftPos + 120, topPos + 111, 16, 20).build()); + next = addRenderableWidget(Button.builder(Component.literal(">>"), b -> step(1)).bounds(leftPos + 180, topPos + 111, 16, 20).build()); previousPage = addRenderableWidget(Button.builder(Component.translatable("gui.mcheli.drafting_table.previous_page"), b -> turnPage(-1)) .bounds(leftPos + 210, topPos + 210, 60, 20).build()); nextPage = addRenderableWidget(Button.builder(Component.translatable("gui.mcheli.drafting_table.next_page"), b -> turnPage(1)) @@ -263,7 +263,8 @@ protected void extractLabels(GuiGraphicsExtractor graphics, int mouseX, int mous } ItemStack result = result(); graphics.text(font, font.plainSubstrByWidth(result.getHoverName().getString(), 85), 120, 20, WHITE, true); - graphics.text(font, (index + 1) + " / " + lists.get(list).size(), 120, 134, TEXT, false); + String position = (index + 1) + " / " + lists.get(list).size(); + graphics.text(font, position, 158 - font.width(position) / 2, 117, TEXT, false); ingredients(graphics, entry.display(), mouseX, mouseY); graphics.item(result, 178, 52); if (pageCount == 0) { diff --git a/minecraft-26.3/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java b/minecraft-26.3/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java index ec38e26d..0328545a 100644 --- a/minecraft-26.3/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java +++ b/minecraft-26.3/src/main/java/com/jnhprojects/mcheli/client/screen/DraftingTableScreen.java @@ -73,7 +73,7 @@ public class DraftingTableScreen extends AbstractContainerScreen create()) .bounds(leftPos + 120, topPos + 89, 50, 20).build()); - previous = addRenderableWidget(Button.builder(Component.literal("<<"), b -> step(-1)).bounds(leftPos + 120, topPos + 111, 36, 20).build()); - next = addRenderableWidget(Button.builder(Component.literal(">>"), b -> step(1)).bounds(leftPos + 155, topPos + 111, 35, 20).build()); + previous = addRenderableWidget(Button.builder(Component.literal("<<"), b -> step(-1)).bounds(leftPos + 120, topPos + 111, 16, 20).build()); + next = addRenderableWidget(Button.builder(Component.literal(">>"), b -> step(1)).bounds(leftPos + 180, topPos + 111, 16, 20).build()); previousPage = addRenderableWidget(Button.builder(Component.translatable("gui.mcheli.drafting_table.previous_page"), b -> turnPage(-1)) .bounds(leftPos + 210, topPos + 210, 60, 20).build()); nextPage = addRenderableWidget(Button.builder(Component.translatable("gui.mcheli.drafting_table.next_page"), b -> turnPage(1)) @@ -263,7 +263,8 @@ protected void extractLabels(GuiGraphicsExtractor graphics, int mouseX, int mous } ItemStack result = result(); graphics.text(font, font.plainSubstrByWidth(result.getHoverName().getString(), 85), 120, 20, WHITE, true); - graphics.text(font, (index + 1) + " / " + lists.get(list).size(), 120, 134, TEXT, false); + String position = (index + 1) + " / " + lists.get(list).size(); + graphics.text(font, position, 158 - font.width(position) / 2, 117, TEXT, false); ingredients(graphics, entry.display(), mouseX, mouseY); graphics.item(result, 178, 52); if (pageCount == 0) {