-
Notifications
You must be signed in to change notification settings - Fork 0
Feat/abstract furnace workbench logic #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
13df396
fix: abstracted furnace logic to an abstract
The-Code-Monkey b848180
feat: loads of changes
The-Code-Monkey 308bb12
feat: recipe works in recipe book
The-Code-Monkey 0f854a0
fix: rename type from alloying
The-Code-Monkey 63935bb
fix: AI comments
The-Code-Monkey a4e45c6
Delete src/main/generated directory
The-Code-Monkey a62db58
Merge branch '1.21' into feat/abstract-furnace-workbench-logic
The-Code-Monkey File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
101 changes: 70 additions & 31 deletions
101
src/client/java/com/tcm/MineTale/block/workbenches/screen/FurnaceWorkbenchScreen.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,65 +1,104 @@ | ||
| package com.tcm.MineTale.block.workbenches.screen; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| import com.tcm.MineTale.MineTale; | ||
| import com.tcm.MineTale.block.workbenches.menu.FurnaceWorkbenchMenu; | ||
| import com.tcm.MineTale.recipe.MineTaleRecipeBookComponent; | ||
| import com.tcm.MineTale.registry.ModBlocks; | ||
|
|
||
| import net.minecraft.client.gui.GuiGraphics; | ||
| import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; | ||
| import net.minecraft.client.gui.navigation.ScreenPosition; | ||
| import net.minecraft.client.gui.screens.inventory.AbstractRecipeBookScreen; | ||
| import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; | ||
| import net.minecraft.client.renderer.RenderPipelines; | ||
| import net.minecraft.resources.Identifier; | ||
| import net.minecraft.world.entity.player.Inventory; | ||
| import net.minecraft.world.item.ItemStack; | ||
| import net.minecraft.world.item.crafting.RecipeBookCategories; | ||
| import net.minecraft.network.chat.Component; | ||
|
|
||
| public class FurnaceWorkbenchScreen extends AbstractContainerScreen<FurnaceWorkbenchMenu> { | ||
| public class FurnaceWorkbenchScreen extends AbstractRecipeBookScreen<FurnaceWorkbenchMenu> { | ||
| private static final Identifier TEXTURE = | ||
| Identifier.fromNamespaceAndPath(MineTale.MOD_ID, "textures/gui/container/furnace_workbench.png"); | ||
|
|
||
| /** | ||
| * Creates a new furnace workbench screen for the given menu, player inventory, and title. | ||
| * | ||
| * @param menu the container menu that provides slots and syncs state for this screen | ||
| * @param inventory the player's inventory to display and interact with | ||
| * @param title the title component shown at the top of the screen | ||
| * Creates a new furnace workbench screen. | ||
| * Note: recipeBookComponent is inherited from AbstractRecipeBookScreen. | ||
| */ | ||
| public FurnaceWorkbenchScreen(FurnaceWorkbenchMenu menu, Inventory inventory, Component title) { | ||
| super(menu, inventory, title); | ||
| super(menu, createRecipeBookComponent(menu), inventory, title); | ||
| } | ||
|
|
||
| /** | ||
| * Initializes the screen and centers the title horizontally by setting {@code titleLabelX}. | ||
| * Static helper to build the component with the custom MineTale tabs. | ||
| * This uses the FURNACE_WORKBENCH icon for this specific screen's tab. | ||
| */ | ||
| private static MineTaleRecipeBookComponent createRecipeBookComponent(FurnaceWorkbenchMenu menu) { | ||
| ItemStack tabIcon = new ItemStack(ModBlocks.FURNACE_WORKBENCH_BLOCK_T1.asItem()); | ||
|
|
||
| List<RecipeBookComponent.TabInfo> tabs = List.of( | ||
| new RecipeBookComponent.TabInfo(tabIcon.getItem(), RecipeBookCategories.CRAFTING_MISC) | ||
| ); | ||
|
|
||
| return new MineTaleRecipeBookComponent(menu, tabs); | ||
| } | ||
|
|
||
| @Override | ||
| protected void init() { | ||
| this.imageWidth = 176; | ||
| this.imageHeight = 166; | ||
|
|
||
| super.init(); | ||
| this.titleLabelX = (this.imageWidth - this.font.width(this.title)) / 2; | ||
|
|
||
| // // Initialize the inherited recipeBookComponent UI state | ||
| // this.recipeBookComponent.init(this.width, this.height, this.minecraft, false); | ||
| // this.leftPos = this.recipeBookComponent.updateScreenPosition(this.width, this.imageWidth); | ||
|
|
||
| // // The toggle button is managed via getRecipeBookButtonPosition() in 1.21.1 | ||
| // // but we add the ImageButton manually to match your CampfireWorkbenchScreen logic exactly. | ||
| // this.addRenderableWidget(new ImageButton( | ||
| // this.leftPos + 5, | ||
| // this.height / 2 - 49, | ||
| // 20, 18, | ||
| // RecipeBookComponent.RECIPE_BUTTON_SPRITES, | ||
| // (button) -> { | ||
| // this.recipeBookComponent.toggleVisibility(); | ||
| // this.leftPos = this.recipeBookComponent.updateScreenPosition(this.width, this.imageWidth); | ||
| // button.setPosition(this.leftPos + 5, this.height / 2 - 49); | ||
| // } | ||
| // )); | ||
| } | ||
|
|
||
| /** | ||
| * Draws the furnace workbench background texture onto the screen. | ||
| * | ||
| * @param guiGraphics the graphics context used for drawing | ||
| * @param f partial tick time used for interpolation | ||
| * @param i current mouse x position | ||
| * @param j current mouse y position | ||
| */ | ||
| protected void renderBg(GuiGraphics guiGraphics, float f, int i, int j) { | ||
| int k = this.leftPos; | ||
| int l = this.topPos; | ||
| guiGraphics.blit(RenderPipelines.GUI_TEXTURED, TEXTURE, k, l, 0.0F, 0.0F, this.imageWidth, this.imageHeight, 256, 256); | ||
| } | ||
| @Override | ||
| protected void renderBg(GuiGraphics guiGraphics, float f, int i, int j) { | ||
| int k = this.leftPos; | ||
| int l = this.topPos; | ||
| guiGraphics.blit(RenderPipelines.GUI_TEXTURED, TEXTURE, k, l, 0.0F, 0.0F, this.imageWidth, this.imageHeight, 256, 256); | ||
| } | ||
|
|
||
| /** | ||
| * Renders the furnace workbench screen, drawing its background, contents, and tooltips. | ||
| * | ||
| * @param graphics the graphics context used for rendering | ||
| * @param mouseX the current mouse X coordinate | ||
| * @param mouseY the current mouse Y coordinate | ||
| * @param delta the frame time delta (partial tick) used for animated rendering | ||
| */ | ||
| @Override | ||
| public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) { | ||
| renderBackground(graphics, mouseX, mouseY, delta); | ||
|
|
||
| // if (this.recipeBookComponent != null) { | ||
| // this.recipeBookComponent.render(graphics, mouseX, mouseY, delta); | ||
| // } | ||
|
|
||
| super.render(graphics, mouseX, mouseY, delta); | ||
|
|
||
| // if (this.recipeBookComponent != null) { | ||
| // this.recipeBookComponent.renderGhostRecipe(graphics, true); | ||
| // this.recipeBookComponent.renderTooltip(graphics, this.leftPos, this.topPos, this.hoveredSlot); | ||
| // } | ||
|
|
||
| renderTooltip(graphics, mouseX, mouseY); | ||
| } | ||
|
|
||
| @Override | ||
| protected ScreenPosition getRecipeBookButtonPosition() { | ||
| int guiLeft = (this.width - this.imageWidth) / 2; | ||
| int guiTop = (this.height - this.imageHeight) / 2; | ||
| return new ScreenPosition(guiLeft + 5, guiTop + this.imageHeight / 2 - 49); | ||
| } | ||
| } |
24 changes: 24 additions & 0 deletions
24
src/client/java/com/tcm/MineTale/mixin/client/ClientRecipeBookMixin.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package com.tcm.MineTale.mixin.client; | ||
|
|
||
| import org.spongepowered.asm.mixin.Mixin; | ||
| import org.spongepowered.asm.mixin.injection.At; | ||
| import org.spongepowered.asm.mixin.injection.Inject; | ||
| import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; | ||
|
|
||
| import com.tcm.MineTale.registry.ModRecipeDisplay; | ||
| import com.tcm.MineTale.registry.ModRecipes; | ||
|
|
||
| import net.minecraft.client.ClientRecipeBook; | ||
| import net.minecraft.world.item.crafting.RecipeBookCategory; | ||
| import net.minecraft.world.item.crafting.RecipeHolder; | ||
|
|
||
| @Mixin(ClientRecipeBook.class) | ||
| public abstract class ClientRecipeBookMixin { | ||
| @Inject(method = "getCategory", at = @At("HEAD"), cancellable = true) | ||
| private static void minetale$addCustomCategory(RecipeHolder<?> recipe, CallbackInfoReturnable<RecipeBookCategory> cir) { | ||
| if (recipe.value().getType() == ModRecipes.FURNACE_SERIALIZER) { | ||
| // This tells the search engine to put your recipes into your custom tab | ||
| cir.setReturnValue(ModRecipeDisplay.CAMPFIRE_SEARCH); | ||
| } | ||
| } | ||
| } |
80 changes: 80 additions & 0 deletions
80
src/client/java/com/tcm/MineTale/recipe/MineTaleRecipeBookComponent.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| package com.tcm.MineTale.recipe; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| import com.tcm.MineTale.registry.ModRecipeDisplay; | ||
| import com.tcm.MineTale.util.Constants; | ||
|
|
||
| import net.minecraft.client.gui.components.WidgetSprites; | ||
| import net.minecraft.client.gui.screens.recipebook.GhostSlots; | ||
| import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; | ||
| import net.minecraft.client.gui.screens.recipebook.RecipeCollection; | ||
| import net.minecraft.network.chat.Component; | ||
| import net.minecraft.resources.Identifier; | ||
| import net.minecraft.util.context.ContextMap; | ||
| import net.minecraft.world.entity.player.StackedItemContents; | ||
| import net.minecraft.world.inventory.RecipeBookMenu; | ||
| import net.minecraft.world.inventory.Slot; | ||
| import net.minecraft.world.item.crafting.display.RecipeDisplay; | ||
|
|
||
| public class MineTaleRecipeBookComponent extends RecipeBookComponent<RecipeBookMenu> { | ||
|
|
||
| // Standard button sprites (the "Filter" checkmark button) | ||
| protected static final WidgetSprites FILTER_BUTTON_SPRITES = new WidgetSprites( | ||
| Identifier.withDefaultNamespace("recipe_book/filter_enabled"), | ||
| Identifier.withDefaultNamespace("recipe_book/filter_disabled"), | ||
| Identifier.withDefaultNamespace("recipe_book/filter_enabled_focused"), | ||
| Identifier.withDefaultNamespace("recipe_book/filter_disabled_focused") | ||
| ); | ||
|
|
||
| public MineTaleRecipeBookComponent(RecipeBookMenu recipeBookMenu, List<TabInfo> list) { | ||
| super(recipeBookMenu, list); | ||
| } | ||
|
|
||
| @Override | ||
| protected void selectMatchingRecipes(RecipeCollection recipeCollection, StackedItemContents stackedItemContents) { | ||
| // Force everything to be "selected" | ||
| // recipeCollection.selectRecipes(stackedItemContents, (recipeDisplay) -> true); | ||
|
|
||
| recipeCollection.selectRecipes(stackedItemContents, (recipeDisplay) -> { | ||
| // Only allow recipes that use your custom Workbench display type | ||
| // This effectively filters out vanilla CraftingRecipeDisplays (the boats) | ||
| return recipeDisplay.type() == ModRecipeDisplay.WORKBENCH_TYPE; | ||
| }); | ||
| } | ||
|
|
||
|
|
||
|
|
||
| @Override | ||
| protected WidgetSprites getFilterButtonTextures() { | ||
| // Returns the textures for the "Toggle craftable" button | ||
| return FILTER_BUTTON_SPRITES; | ||
| } | ||
|
|
||
| @Override | ||
| protected boolean isCraftingSlot(Slot slot) { | ||
| return slot.index == Constants.INPUT_START || slot.index == Constants.INPUT_START + 1; | ||
| } | ||
|
|
||
| @Override | ||
| protected Component getRecipeFilterName() { | ||
| // The text shown when hovering over the filter button | ||
| return Component.translatable("gui.recipebook.toggleRecipes.all"); | ||
| } | ||
|
|
||
| @Override | ||
| protected void fillGhostRecipe(GhostSlots ghostSlots, RecipeDisplay recipeDisplay, ContextMap contextMap) { | ||
| // This places the faint "ghost" items in the workbench slots when hovering a recipe | ||
| // We use SlotDisplayContext.fromLevel(this.minecraft.level) to handle dynamic displays | ||
| // ghostSlots.setRecipe(recipeDisplay); | ||
|
|
||
| // // We assume the first two slots of your menu are the inputs | ||
| // // Your AbstractWorkbenchContainerMenu adds input slots first (index 0 and 1) | ||
| // ghostSlots.addSlot(this.menu.slots.get(0), this.minecraft.level.registryAccess(), recipeDisplay.result()); | ||
|
|
||
| // // If your custom recipe has specific inputs, you'd map them here. | ||
| // // For a generic implementation, we use the display's suggested placement: | ||
| // recipeDisplay.setupGhostSlots(ghostSlots, SlotDisplayContext.fromLevel(this.minecraft.level)); | ||
| } | ||
|
|
||
| } | ||
16 changes: 16 additions & 0 deletions
16
src/client/java/net/minecraft/client/gui/screens/recipebook/GhostSlotsProxy.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package net.minecraft.client.gui.screens.recipebook; | ||
|
|
||
| import net.minecraft.world.inventory.Slot; | ||
| import net.minecraft.util.context.ContextMap; | ||
| import net.minecraft.world.item.crafting.display.SlotDisplay; | ||
|
|
||
| public class GhostSlotsProxy { | ||
| public static void setInputProxy(GhostSlots ghostSlots, Slot slot, ContextMap contextMap, SlotDisplay display) { | ||
| // Because this class is in the same package, it can see protected methods! | ||
| ghostSlots.setInput(slot, contextMap, display); | ||
| } | ||
|
|
||
| public static void setResultProxy(GhostSlots ghostSlots, Slot slot, ContextMap contextMap, SlotDisplay display) { | ||
| ghostSlots.setResult(slot, contextMap, display); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Empty
fillGhostRecipeimplementation breaks ghost recipe display.The method body is entirely commented out, so hovering over recipes in the book won't show ghost items in the crafting slots. This degrades the recipe book UX—users expect to see ingredient hints.
Either implement the ghost slot logic or add a clear
// TODO:explaining why it's deferred and what's blocking completion.Would you like help implementing the ghost recipe logic based on the commented hints?
🤖 Prompt for AI Agents
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ignore for now not sure how to do it due to GhostSlots functions all being private.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@The-Code-Monkey, understood! I see you've already createdGhostSlotsProxy.javain this PR to work around the package-private methods inGhostSlots(withsetInputProxyandsetResultProxy). If you need additionalGhostSlotsmethods exposed, you can add more proxy methods to that class following the same pattern.Feel free to implement this when you're ready or when you've figured out the full set of methods needed for the ghost recipe logic.