Skip to content

Commit ccb4650

Browse files
feat: give other block entities access to display the new recipe item requirements
1 parent 6062097 commit ccb4650

File tree

6 files changed

+114
-79
lines changed

6 files changed

+114
-79
lines changed

src/client/java/com/tcm/MineTale/block/workbenches/screen/ArmorersWorkbenchScreen.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
import net.minecraft.world.item.crafting.display.SlotDisplayContext;
3636
import net.minecraft.network.chat.Component;
3737

38-
public class ArmorersWorkbenchScreen extends AbstractRecipeBookScreen<ArmorersWorkbenchMenu> {
38+
public class ArmorersWorkbenchScreen extends ModAbstractContainerScreen<ArmorersWorkbenchMenu> {
3939
private static final Identifier TEXTURE =
4040
Identifier.fromNamespaceAndPath(MineTale.MOD_ID, "textures/gui/container/workbench_workbench.png");
4141

@@ -189,6 +189,9 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
189189
this.craftOneBtn.active = canCraftOne;
190190
this.craftTenBtn.active = canCraftTen;
191191
this.craftAllBtn.active = canCraftMoreThanOne;
192+
193+
// NEW: Render the Ingredients List
194+
this.renderIngredientList(graphics, selectedEntry, mouseX, mouseY);
192195
} else {
193196
this.craftOneBtn.active = false;
194197
this.craftTenBtn.active = false;

src/client/java/com/tcm/MineTale/block/workbenches/screen/BuildersWorkbenchScreen.java

Lines changed: 5 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import net.minecraft.client.gui.GuiGraphics;
2121
import net.minecraft.client.gui.components.Button;
2222
import net.minecraft.client.gui.navigation.ScreenPosition;
23-
import net.minecraft.client.gui.screens.inventory.AbstractRecipeBookScreen;
2423
import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent;
2524
import net.minecraft.client.renderer.RenderPipelines;
2625
import net.minecraft.core.Holder;
@@ -34,8 +33,9 @@
3433
import net.minecraft.world.item.crafting.display.RecipeDisplayId;
3534
import net.minecraft.world.item.crafting.display.SlotDisplayContext;
3635
import net.minecraft.network.chat.Component;
36+
import org.jspecify.annotations.NonNull;
3737

38-
public class BuildersWorkbenchScreen extends AbstractRecipeBookScreen<BuildersWorkbenchMenu> {
38+
public class BuildersWorkbenchScreen extends ModAbstractContainerScreen<BuildersWorkbenchMenu> {
3939
private static final Identifier TEXTURE =
4040
Identifier.fromNamespaceAndPath(MineTale.MOD_ID, "textures/gui/container/workbench_workbench.png");
4141

@@ -159,8 +159,8 @@ protected void renderBg(GuiGraphics guiGraphics, float f, int i, int j) {
159159
guiGraphics.blit(RenderPipelines.GUI_TEXTURED, TEXTURE, k, l, 0.0F, 0.0F, this.imageWidth, this.imageHeight, 256, 256);
160160
}
161161

162-
@Override
163-
public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
162+
@Override
163+
public void render(@NonNull GuiGraphics graphics, int mouseX, int mouseY, float delta) {
164164
renderBackground(graphics, mouseX, mouseY, delta);
165165
super.render(graphics, mouseX, mouseY, delta);
166166

@@ -186,7 +186,7 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
186186
this.craftAllBtn.active = canCraftMoreThanOne;
187187

188188
// NEW: Render the Ingredients List
189-
renderIngredientList(graphics, selectedEntry, mouseX, mouseY);
189+
this.renderIngredientList(graphics, selectedEntry, mouseX, mouseY);
190190
} else {
191191
this.craftOneBtn.active = false;
192192
this.craftTenBtn.active = false;
@@ -196,75 +196,6 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
196196
renderTooltip(graphics, mouseX, mouseY);
197197
}
198198

199-
private void renderIngredientList(GuiGraphics graphics, RecipeDisplayEntry entry, int mouseX, int mouseY) {
200-
Optional<List<Ingredient>> reqs = entry.craftingRequirements();
201-
if (reqs.isEmpty()) return;
202-
203-
// Group requirements to avoid duplicate rows for the same item type
204-
Map<List<Holder<Item>>, Integer> aggregated = new HashMap<>();
205-
Map<List<Holder<Item>>, Ingredient> holderToIng = new HashMap<>();
206-
207-
for (Ingredient ing : reqs.get()) {
208-
List<Holder<Item>> key = ing.items().toList();
209-
aggregated.put(key, aggregated.getOrDefault(key, 0) + 1);
210-
holderToIng.putIfAbsent(key, ing);
211-
}
212-
213-
int startX = this.leftPos + 8; // Adjust to fit your texture's empty space
214-
int startY = this.topPos + 20;
215-
int rowHeight = 20;
216-
int index = 0;
217-
218-
for (Map.Entry<List<Holder<Item>>, Integer> reqEntry : aggregated.entrySet()) {
219-
Ingredient ing = holderToIng.get(reqEntry.getKey());
220-
int amountNeeded = reqEntry.getValue();
221-
int currentY = startY + (index * rowHeight);
222-
223-
// Calculate total available (Inv + Nearby)
224-
int available = getAvailableCount(ing);
225-
226-
// Draw Item Icon
227-
// Inside your loop
228-
ItemStack[] variants = ing.items().map(ItemStack::new).toArray(ItemStack[]::new);
229-
if (variants.length > 0) {
230-
long time = System.currentTimeMillis() / 1000;
231-
ItemStack displayStack = variants[(int) (time % variants.length)];
232-
233-
graphics.renderFakeItem(displayStack, startX, currentY);
234-
235-
int color = (available < amountNeeded) ? 0xFFFF5555 : 0xFFFFFFFF; // Added alpha channel
236-
String progress = available + "/" + amountNeeded;
237-
graphics.drawString(this.font, progress, startX + 22, currentY + 4, color);
238-
239-
if (mouseX >= startX && mouseX <= startX + 16 && mouseY >= currentY && mouseY <= currentY + 16) {
240-
graphics.setTooltipForNextFrame(this.font, displayStack, mouseX, mouseY);
241-
}
242-
}
243-
index++;
244-
}
245-
}
246-
247-
private int getAvailableCount(Ingredient ingredient) {
248-
int found = 0;
249-
// Check Player Inventory
250-
// Use getContainerSize() and getItem(i) for safe access
251-
Inventory inv = this.minecraft.player.getInventory();
252-
for (int i = 0; i < inv.getContainerSize(); i++) {
253-
ItemStack stack = inv.getItem(i);
254-
if (ingredient.test(stack)) {
255-
found += stack.getCount();
256-
}
257-
}
258-
259-
// Check Networked Nearby Items
260-
if (this.menu instanceof AbstractWorkbenchContainerMenu workbenchMenu) {
261-
for (ItemStack stack : workbenchMenu.getNetworkedNearbyItems()) {
262-
if (ingredient.test(stack)) found += stack.getCount();
263-
}
264-
}
265-
return found;
266-
}
267-
268199
/**
269200
* Determines whether the player has enough ingredients to craft the given recipe the specified number of times.
270201
*

src/client/java/com/tcm/MineTale/block/workbenches/screen/FarmersWorkbenchScreen.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
import net.minecraft.world.item.crafting.display.SlotDisplayContext;
3636
import net.minecraft.network.chat.Component;
3737

38-
public class FarmersWorkbenchScreen extends AbstractRecipeBookScreen<FarmersWorkbenchMenu> {
38+
public class FarmersWorkbenchScreen extends ModAbstractContainerScreen<FarmersWorkbenchMenu> {
3939
private static final Identifier TEXTURE =
4040
Identifier.fromNamespaceAndPath(MineTale.MOD_ID, "textures/gui/container/workbench_workbench.png");
4141

@@ -198,6 +198,9 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
198198
this.craftOneBtn.active = canCraftOne;
199199
this.craftTenBtn.active = canCraftTen;
200200
this.craftAllBtn.active = canCraftMoreThanOne;
201+
202+
// NEW: Render the Ingredients List
203+
this.renderIngredientList(graphics, selectedEntry, mouseX, mouseY);
201204
} else {
202205
this.craftOneBtn.active = false;
203206
this.craftTenBtn.active = false;
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.tcm.MineTale.block.workbenches.screen;
2+
3+
import com.tcm.MineTale.block.workbenches.menu.AbstractWorkbenchContainerMenu;
4+
5+
import net.minecraft.client.gui.GuiGraphics;
6+
import net.minecraft.client.gui.screens.inventory.AbstractRecipeBookScreen;
7+
import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent;
8+
import net.minecraft.core.Holder;
9+
import net.minecraft.network.chat.Component;
10+
import net.minecraft.world.entity.player.Inventory;
11+
import net.minecraft.world.item.Item;
12+
import net.minecraft.world.item.ItemStack;
13+
import net.minecraft.world.item.crafting.Ingredient;
14+
import net.minecraft.world.item.crafting.display.RecipeDisplayEntry;
15+
16+
import java.util.HashMap;
17+
import java.util.List;
18+
import java.util.Map;
19+
import java.util.Optional;
20+
21+
22+
public abstract class ModAbstractContainerScreen<T extends AbstractWorkbenchContainerMenu> extends AbstractRecipeBookScreen<T> {
23+
24+
public ModAbstractContainerScreen(T recipeBookMenu, RecipeBookComponent<?> recipeBookComponent, Inventory inventory, Component component) {
25+
super(recipeBookMenu, recipeBookComponent, inventory, component);
26+
}
27+
28+
protected void renderIngredientList(GuiGraphics graphics, RecipeDisplayEntry entry, int mouseX, int mouseY) {
29+
Optional<List<Ingredient>> reqs = entry.craftingRequirements();
30+
if (reqs.isEmpty()) return;
31+
32+
// Group requirements to avoid duplicate rows for the same item type
33+
Map<List<Holder<Item>>, Integer> aggregated = new HashMap<>();
34+
Map<List<Holder<Item>>, Ingredient> holderToIng = new HashMap<>();
35+
36+
for (Ingredient ing : reqs.get()) {
37+
List<Holder<Item>> key = ing.items().toList();
38+
aggregated.put(key, aggregated.getOrDefault(key, 0) + 1);
39+
holderToIng.putIfAbsent(key, ing);
40+
}
41+
42+
int startX = this.leftPos + 8; // Adjust to fit your texture's empty space
43+
int startY = this.topPos + 20;
44+
int rowHeight = 20;
45+
int index = 0;
46+
47+
for (Map.Entry<List<Holder<Item>>, Integer> reqEntry : aggregated.entrySet()) {
48+
Ingredient ing = holderToIng.get(reqEntry.getKey());
49+
int amountNeeded = reqEntry.getValue();
50+
int currentY = startY + (index * rowHeight);
51+
52+
// Calculate total available (Inv + Nearby)
53+
int available = getAvailableCount(ing);
54+
55+
// Draw Item Icon
56+
// Inside your loop
57+
ItemStack[] variants = ing.items().map(ItemStack::new).toArray(ItemStack[]::new);
58+
if (variants.length > 0) {
59+
long time = System.currentTimeMillis() / 1000;
60+
ItemStack displayStack = variants[(int) (time % variants.length)];
61+
62+
graphics.renderFakeItem(displayStack, startX, currentY);
63+
64+
int color = (available < amountNeeded) ? 0xFFFF5555 : 0xFFFFFFFF; // Added alpha channel
65+
String progress = available + "/" + amountNeeded;
66+
graphics.drawString(this.font, progress, startX + 22, currentY + 4, color);
67+
68+
if (mouseX >= startX && mouseX <= startX + 16 && mouseY >= currentY && mouseY <= currentY + 16) {
69+
graphics.setTooltipForNextFrame(this.font, displayStack, mouseX, mouseY);
70+
}
71+
}
72+
index++;
73+
}
74+
}
75+
76+
private int getAvailableCount(Ingredient ingredient) {
77+
int found = 0;
78+
// Check Player Inventory
79+
// Use getContainerSize() and getItem(i) for safe access
80+
Inventory inv = this.minecraft.player.getInventory();
81+
for (int i = 0; i < inv.getContainerSize(); i++) {
82+
ItemStack stack = inv.getItem(i);
83+
if (ingredient.test(stack)) {
84+
found += stack.getCount();
85+
}
86+
}
87+
88+
// Check Networked Nearby Items
89+
if (this.menu instanceof AbstractWorkbenchContainerMenu workbenchMenu) {
90+
for (ItemStack stack : workbenchMenu.getNetworkedNearbyItems()) {
91+
if (ingredient.test(stack)) found += stack.getCount();
92+
}
93+
}
94+
return found;
95+
}
96+
}

src/client/java/com/tcm/MineTale/block/workbenches/screen/WorkbenchWorkbenchScreen.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
import net.minecraft.world.item.crafting.display.SlotDisplayContext;
3636
import net.minecraft.network.chat.Component;
3737

38-
public class WorkbenchWorkbenchScreen extends AbstractRecipeBookScreen<WorkbenchWorkbenchMenu> {
38+
public class WorkbenchWorkbenchScreen extends ModAbstractContainerScreen<WorkbenchWorkbenchMenu> {
3939
private static final Identifier TEXTURE =
4040
Identifier.fromNamespaceAndPath(MineTale.MOD_ID, "textures/gui/container/workbench_workbench.png");
4141

@@ -197,6 +197,9 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
197197
this.craftOneBtn.active = canCraftOne;
198198
this.craftTenBtn.active = canCraftTen;
199199
this.craftAllBtn.active = canCraftMoreThanOne;
200+
201+
// NEW: Render the Ingredients List
202+
this.renderIngredientList(graphics, selectedEntry, mouseX, mouseY);
200203
} else {
201204
this.craftOneBtn.active = false;
202205
this.craftTenBtn.active = false;

src/main/java/com/tcm/MineTale/block/workbenches/menu/AbstractWorkbenchContainerMenu.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.tcm.MineTale.block.workbenches.menu;
22

3-
import java.util.ArrayList;
4-
import java.util.List;
3+
import java.util.*;
54

65
import org.jspecify.annotations.Nullable;
76

0 commit comments

Comments
 (0)