@@ -146,10 +146,10 @@ private void handleCraftRequest(int amount) {
146146 }
147147
148148 /**
149- * Render the workbench background texture at the screen's top-left corner.
149+ * Draws the workbench GUI background texture at the screen's top-left corner.
150150 *
151151 * @param guiGraphics the graphics context used to draw GUI elements
152- * @param f partial tick time used for animation interpolation
152+ * @param f partial tick time for interpolation
153153 * @param i current mouse x coordinate relative to the window
154154 * @param j current mouse y coordinate relative to the window
155155 */
@@ -159,51 +159,36 @@ 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- /**
163- * Renders the builders workbench screen, updates recipe selection state, updates craft button availability
164- * and, when a recipe is selected, renders its ingredient list and hover tooltips.
165- *
166- * The method:
167- * - draws the background and base screen,
168- * - updates {@code lastKnownSelectedId} from the recipe book component,
169- * - looks up the corresponding {@code RecipeDisplayEntry} from the client's known recipes,
170- * - enables or disables the craft buttons according to available ingredients for 1, 2 and 10 crafts,
171- * - renders the aggregated ingredient list for the selected recipe (including hover tooltips) when present,
172- * - renders the standard screen tooltip layer.
173- *
174- * @param graphics the GUI graphics context used for all rendering operations
175- * @param mouseX current mouse X coordinate (screen space)
176- * @param mouseY current mouse Y coordinate (screen space)
177- * @param delta frame partial tick time used for animated displays
178- */
179162 @ Override
180163 public void render (GuiGraphics graphics , int mouseX , int mouseY , float delta ) {
181164 renderBackground (graphics , mouseX , mouseY , delta );
182165 super .render (graphics , mouseX , mouseY , delta );
183166
167+ // 1. Get the current selection from the book
184168 RecipeDisplayId currentId = this .mineTaleRecipeBook .getSelectedRecipeId ();
169+
170+ // 2. If it's NOT null, remember it!
185171 if (currentId != null ) {
186172 this .lastKnownSelectedId = currentId ;
187173 }
188174
175+ // 3. Use the remembered ID to find the entry for button activation
189176 RecipeDisplayEntry selectedEntry = null ;
190177 if (this .lastKnownSelectedId != null && this .minecraft .level != null ) {
191178 ClientRecipeBook book = this .minecraft .player .getRecipeBook ();
192179 selectedEntry = ((ClientRecipeBookAccessor ) book ).getKnown ().get (this .lastKnownSelectedId );
193180 }
194181
182+ // 2. Button Activation Logic
195183 if (selectedEntry != null ) {
196- // Existing Button Logic
184+ // We use the entry directly. It contains the 15 ingredients needed!
197185 boolean canCraftOne = canCraft (this .minecraft .player , selectedEntry , 1 );
198186 boolean canCraftMoreThanOne = canCraft (this .minecraft .player , selectedEntry , 2 );
199187 boolean canCraftTen = canCraft (this .minecraft .player , selectedEntry , 10 );
200188
201189 this .craftOneBtn .active = canCraftOne ;
202190 this .craftTenBtn .active = canCraftTen ;
203191 this .craftAllBtn .active = canCraftMoreThanOne ;
204-
205- // NEW: Render the Ingredients List
206- renderIngredientList (graphics , selectedEntry , mouseX , mouseY );
207192 } else {
208193 this .craftOneBtn .active = false ;
209194 this .craftTenBtn .active = false ;
@@ -213,94 +198,6 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
213198 renderTooltip (graphics , mouseX , mouseY );
214199 }
215200
216- /**
217- * Render the aggregated ingredient list for a recipe, showing icons, availability and tooltips.
218- *
219- * <p>For the given recipe this draws one row per unique ingredient set (duplicates aggregated),
220- * cycles through item variants for the icon, renders an availability string "available/needed"
221- * (red when insufficient, white when sufficient) and shows an item tooltip when the mouse
222- * hovers over the icon.
223- *
224- * @param graphics the GUI graphics context used for rendering
225- * @param entry the recipe entry whose crafting requirements will be displayed
226- * @param mouseX the current mouse X coordinate (used to detect tooltip hover)
227- * @param mouseY the current mouse Y coordinate (used to detect tooltip hover)
228- */
229- private void renderIngredientList (GuiGraphics graphics , RecipeDisplayEntry entry , int mouseX , int mouseY ) {
230- Optional <List <Ingredient >> reqs = entry .craftingRequirements ();
231- if (reqs .isEmpty ()) return ;
232-
233- // Group requirements to avoid duplicate rows for the same item type
234- Map <List <Holder <Item >>, Integer > aggregated = new HashMap <>();
235- Map <List <Holder <Item >>, Ingredient > holderToIng = new HashMap <>();
236-
237- for (Ingredient ing : reqs .get ()) {
238- List <Holder <Item >> key = ing .items ().toList ();
239- aggregated .put (key , aggregated .getOrDefault (key , 0 ) + 1 );
240- holderToIng .putIfAbsent (key , ing );
241- }
242-
243- int startX = this .leftPos + 8 ; // Adjust to fit your texture's empty space
244- int startY = this .topPos + 20 ;
245- int rowHeight = 20 ;
246- int index = 0 ;
247-
248- for (Map .Entry <List <Holder <Item >>, Integer > reqEntry : aggregated .entrySet ()) {
249- Ingredient ing = holderToIng .get (reqEntry .getKey ());
250- int amountNeeded = reqEntry .getValue ();
251- int currentY = startY + (index * rowHeight );
252-
253- // Calculate total available (Inv + Nearby)
254- int available = getAvailableCount (ing );
255-
256- // Draw Item Icon
257- ItemStack [] variants = ing .items ().toArray (ItemStack []::new );
258- if (variants .length > 0 ) {
259- // Cycle through variants every second
260- ItemStack displayStack = variants [(int ) (System .currentTimeMillis () / 1000 % variants .length )];
261- graphics .renderFakeItem (displayStack , startX , currentY );
262-
263- // Draw Text (Red if lacking, White if okay)
264- int color = (available < amountNeeded ) ? 0xFF5555 : 0xFFFFFF ;
265- String progress = available + "/" + amountNeeded ;
266- graphics .drawString (this .font , progress , startX + 20 , currentY + 4 , color , true );
267-
268- // Tooltip logic
269- if (mouseX >= startX && mouseX < startX + 16 && mouseY >= currentY && mouseY < currentY + 16 ) {
270- graphics .renderItemTooltip (this .font , displayStack , mouseX , mouseY );
271- }
272- }
273- index ++;
274- }
275- }
276-
277- /**
278- * Count the total quantity of items that satisfy the given ingredient from the player inventory and nearby networked storage.
279- *
280- * @param ingredient the ingredient used to test ItemStacks
281- * @return the sum of counts of all ItemStacks matching `ingredient` from the player inventory and any networked nearby items
282- */
283- private int getAvailableCount (Ingredient ingredient ) {
284- int found = 0 ;
285- // Check Player Inventory
286- // Use getContainerSize() and getItem(i) for safe access
287- Inventory inv = this .minecraft .player .getInventory ();
288- for (int i = 0 ; i < inv .getContainerSize (); i ++) {
289- ItemStack stack = inv .getItem (i );
290- if (ingredient .test (stack )) {
291- found += stack .getCount ();
292- }
293- }
294-
295- // Check Networked Nearby Items
296- if (this .menu instanceof AbstractWorkbenchContainerMenu workbenchMenu ) {
297- for (ItemStack stack : workbenchMenu .getNetworkedNearbyItems ()) {
298- if (ingredient .test (stack )) found += stack .getCount ();
299- }
300- }
301- return found ;
302- }
303-
304201 /**
305202 * Determines whether the player has enough ingredients to craft the given recipe the specified number of times.
306203 *
@@ -384,9 +281,9 @@ private boolean hasIngredientAmount(Inventory inventory, Ingredient ingredient,
384281 }
385282
386283 /**
387- * Compute the on-screen position for the recipe- book toggle button for this GUI.
284+ * Computes the on-screen position for the recipe book toggle button for this GUI.
388285 *
389- * @return the screen position located 5 pixels from the GUI's left edge and 49 pixels above the GUI's vertical centre
286+ * @return the screen position placed 5 pixels from the GUI's left edge and 49 pixels above the GUI's vertical center
390287 */
391288 @ Override
392289 protected ScreenPosition getRecipeBookButtonPosition () {
@@ -400,4 +297,4 @@ protected ScreenPosition getRecipeBookButtonPosition() {
400297 // Usually 5 pixels in from the left and 49 pixels up from the center
401298 return new ScreenPosition (guiLeft + 5 , guiTop + this .imageHeight / 2 - 49 );
402299 }
403- }
300+ }
0 commit comments