Skip to content

Commit 468419c

Browse files
fix: furnace now works with its own recipes
1 parent 7e8066d commit 468419c

13 files changed

Lines changed: 164 additions & 87 deletions

File tree

src/client/java/com/tcm/MineTale/MineTaleClient.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
package com.tcm.MineTale;
22

33
import com.tcm.MineTale.block.workbenches.screen.FurnaceWorkbenchScreen;
4+
5+
import java.util.List;
6+
47
import com.tcm.MineTale.block.workbenches.screen.CampfireWorkbenchScreen;
58
import com.tcm.MineTale.registry.ModMenuTypes;
9+
import com.tcm.MineTale.registry.ModRecipeDisplay;
10+
import com.tcm.MineTale.registry.ModRecipes;
611

712
import net.fabricmc.api.ClientModInitializer;
813
import net.minecraft.client.gui.screens.MenuScreens;
14+
import net.minecraft.world.item.crafting.RecipeBookCategories;
915

1016
public class MineTaleClient implements ClientModInitializer {
1117

@@ -21,7 +27,5 @@ public class MineTaleClient implements ClientModInitializer {
2127
public void onInitializeClient() {
2228
MenuScreens.register(ModMenuTypes.FURNACE_WORKBENCH_MENU, FurnaceWorkbenchScreen::new);
2329
MenuScreens.register(ModMenuTypes.CAMPFIRE_WORKBENCH_MENU, CampfireWorkbenchScreen::new);
24-
25-
2630
}
2731
}

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

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.tcm.MineTale.block.workbenches.menu.FurnaceWorkbenchMenu;
77
import com.tcm.MineTale.recipe.MineTaleRecipeBookComponent;
88
import com.tcm.MineTale.registry.ModBlocks;
9+
import com.tcm.MineTale.registry.ModRecipeDisplay;
910
import com.tcm.MineTale.registry.ModRecipes;
1011

1112
import net.minecraft.client.gui.GuiGraphics;
@@ -16,7 +17,6 @@
1617
import net.minecraft.resources.Identifier;
1718
import net.minecraft.world.entity.player.Inventory;
1819
import net.minecraft.world.item.ItemStack;
19-
import net.minecraft.world.item.crafting.RecipeBookCategories;
2020
import net.minecraft.network.chat.Component;
2121

2222
public class FurnaceWorkbenchScreen extends AbstractRecipeBookScreen<FurnaceWorkbenchMenu> {
@@ -39,10 +39,14 @@ private static MineTaleRecipeBookComponent createRecipeBookComponent(FurnaceWork
3939
ItemStack tabIcon = new ItemStack(ModBlocks.FURNACE_WORKBENCH_BLOCK_T1.asItem());
4040

4141
List<RecipeBookComponent.TabInfo> tabs = List.of(
42-
new RecipeBookComponent.TabInfo(tabIcon.getItem(), RecipeBookCategories.CRAFTING_MISC)
42+
new RecipeBookComponent.TabInfo(tabIcon.getItem(), ModRecipeDisplay.FURNACE_T1_SEARCH)
4343
);
44+
// List<RecipeBookComponent.TabInfo> tabs = List.of(
45+
// new RecipeBookComponent.TabInfo(tabIcon.getItem(), ModRecipeDisplay.CAMPFIRE_SEARCH)
46+
// );
4447

45-
return new MineTaleRecipeBookComponent(menu, tabs, ModRecipes.FURNACE_TYPE);
48+
// Ensure the last argument is the RecipeBookType, NOT the RecipeType
49+
return new MineTaleRecipeBookComponent(menu, tabs, ModRecipes.FURNACE_T1_TYPE);
4650
}
4751

4852
@Override
@@ -82,17 +86,8 @@ protected void renderBg(GuiGraphics guiGraphics, float f, int i, int j) {
8286
public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
8387
renderBackground(graphics, mouseX, mouseY, delta);
8488

85-
// if (this.recipeBookComponent != null) {
86-
// this.recipeBookComponent.render(graphics, mouseX, mouseY, delta);
87-
// }
88-
8989
super.render(graphics, mouseX, mouseY, delta);
9090

91-
// if (this.recipeBookComponent != null) {
92-
// this.recipeBookComponent.renderGhostRecipe(graphics, true);
93-
// this.recipeBookComponent.renderTooltip(graphics, this.leftPos, this.topPos, this.hoveredSlot);
94-
// }
95-
9691
renderTooltip(graphics, mouseX, mouseY);
9792
}
9893

src/client/java/com/tcm/MineTale/datagen/ModRecipeProvider.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import com.tcm.MineTale.MineTale;
66
import com.tcm.MineTale.datagen.builders.WorkbenchRecipeBuilder;
7+
import com.tcm.MineTale.registry.ModRecipeDisplay;
78
import com.tcm.MineTale.registry.ModRecipes;
89

910
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
@@ -51,15 +52,17 @@ public void buildRecipes() {
5152
.time(10) // Campfires usually take longer (30 seconds)
5253
.unlockedBy("has_porkchop", has(Items.PORKCHOP))
5354
.category(CraftingBookCategory.MISC)
55+
.bookCategory(ModRecipeDisplay.CAMPFIRE_SEARCH)
5456
.save(exporter, Identifier.fromNamespaceAndPath(MineTale.MOD_ID, "campfire_pork_cooking"));
5557

56-
new WorkbenchRecipeBuilder(ModRecipes.FURNACE_TYPE, ModRecipes.FURNACE_SERIALIZER)
58+
new WorkbenchRecipeBuilder(ModRecipes.FURNACE_T1_TYPE, ModRecipes.FURNACE_SERIALIZER)
5759
.input(Ingredient.of(Items.PORKCHOP))
5860
// Note: Slot 1 is optional in our logic, so we just don't add a second input
59-
.output(new ItemStack(Items.COOKED_PORKCHOP))
61+
.output(new ItemStack(Items.ACACIA_BOAT))
6062
.time(10) // Campfires usually take longer (30 seconds)
6163
.unlockedBy("has_porkchop", has(Items.PORKCHOP))
6264
.category(CraftingBookCategory.MISC)
65+
.bookCategory(ModRecipeDisplay.FURNACE_T1_SEARCH)
6366
.save(exporter, Identifier.fromNamespaceAndPath(MineTale.MOD_ID, "furnace_pork_cooking"));
6467
}
6568
};

src/client/java/com/tcm/MineTale/datagen/builders/WorkbenchRecipeBuilder.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@
1111
import com.mojang.serialization.MapCodec;
1212
import com.mojang.serialization.codecs.RecordCodecBuilder;
1313
import com.tcm.MineTale.recipe.WorkbenchRecipe;
14+
import com.tcm.MineTale.registry.ModRecipeDisplay;
1415

1516
import net.minecraft.advancements.Advancement;
1617
import net.minecraft.advancements.AdvancementRequirements;
1718
import net.minecraft.advancements.AdvancementRewards;
1819
import net.minecraft.advancements.Criterion;
1920
import net.minecraft.advancements.criterion.RecipeUnlockedTrigger;
21+
import net.minecraft.core.registries.BuiltInRegistries;
2022
import net.minecraft.core.registries.Registries;
2123
import net.minecraft.data.recipes.RecipeBuilder;
2224
import net.minecraft.data.recipes.RecipeOutput;
@@ -28,6 +30,7 @@
2830
import net.minecraft.world.item.crafting.CraftingBookCategory;
2931
import net.minecraft.world.item.crafting.Ingredient;
3032
import net.minecraft.world.item.crafting.Recipe;
33+
import net.minecraft.world.item.crafting.RecipeBookCategory;
3134
import net.minecraft.world.item.crafting.RecipeSerializer;
3235
import net.minecraft.world.item.crafting.RecipeType;
3336

@@ -38,6 +41,8 @@ public class WorkbenchRecipeBuilder implements RecipeBuilder {
3841
private final List<ItemStack> results = new ArrayList<>();
3942
private final Map<String, Criterion<?>> criteria = new LinkedHashMap<>();
4043
private CraftingBookCategory category = CraftingBookCategory.MISC;
44+
private Identifier bookCategory = BuiltInRegistries.RECIPE_BOOK_CATEGORY
45+
.getKey(ModRecipeDisplay.CAMPFIRE_SEARCH);
4146
private int cookTime = 200;
4247
@Nullable private String group;
4348

@@ -56,9 +61,11 @@ public static final MapCodec<WorkbenchRecipe> CODEC(RecipeType<WorkbenchRecipe>
5661
ItemStack.STRICT_CODEC.listOf().fieldOf("results").forGetter(WorkbenchRecipe::results),
5762
Codec.INT.optionalFieldOf("cookTime", 200).forGetter(WorkbenchRecipe::cookTime),
5863
// Updated to CraftingBookCategory codec
59-
CraftingBookCategory.CODEC.optionalFieldOf("category", CraftingBookCategory.MISC).forGetter(WorkbenchRecipe::category)
60-
).apply(inst, (ingredients, results, cookTime, category) ->
61-
new WorkbenchRecipe(ingredients, results, cookTime, type, serializer, category)
64+
CraftingBookCategory.CODEC.optionalFieldOf("category", CraftingBookCategory.MISC).forGetter(WorkbenchRecipe::category),
65+
Identifier.CODEC.fieldOf("book_category").forGetter(WorkbenchRecipe::bookCategory)
66+
).apply(inst, (ingredients, results, cookTime, category, bookCategory) ->
67+
// 2. Pass the new bookCategory into the constructor
68+
new WorkbenchRecipe(ingredients, results, cookTime, type, serializer, category, bookCategory)
6269
));
6370
}
6471

@@ -100,6 +107,15 @@ public WorkbenchRecipeBuilder category(CraftingBookCategory category) {
100107
return this;
101108
}
102109

110+
public WorkbenchRecipeBuilder bookCategory(RecipeBookCategory category) {
111+
Identifier id = BuiltInRegistries.RECIPE_BOOK_CATEGORY.getKey(category);
112+
if (id != null) {
113+
this.bookCategory = id;
114+
}
115+
return this;
116+
}
117+
118+
103119
/**
104120
* Adds an output item stack to the recipe.
105121
*
@@ -201,7 +217,8 @@ public void save(RecipeOutput recipeOutput, ResourceKey<Recipe<?>> resourceKey)
201217
cookTime,
202218
this.type,
203219
this.serializer,
204-
this.category
220+
this.category,
221+
this.bookCategory
205222
);
206223

207224
// 4. Accept the recipe into the generator

src/client/java/com/tcm/MineTale/mixin/client/ClientRecipeBookMixin.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,19 @@
1111
import net.minecraft.client.ClientRecipeBook;
1212
import net.minecraft.world.item.crafting.RecipeBookCategory;
1313
import net.minecraft.world.item.crafting.RecipeHolder;
14+
import net.minecraft.world.item.crafting.RecipeType;
1415

1516
@Mixin(ClientRecipeBook.class)
1617
public abstract class ClientRecipeBookMixin {
1718
@Inject(method = "getCategory", at = @At("HEAD"), cancellable = true)
1819
private static void minetale$addCustomCategory(RecipeHolder<?> recipe, CallbackInfoReturnable<RecipeBookCategory> cir) {
19-
if (recipe.value().getType() == ModRecipes.FURNACE_SERIALIZER) {
20-
// This tells the search engine to put your recipes into your custom tab
20+
RecipeType<?> type = recipe.value().getType();
21+
22+
// Using .equals() satisfies the compiler
23+
if (ModRecipes.CAMPFIRE_TYPE.equals(type)) {
2124
cir.setReturnValue(ModRecipeDisplay.CAMPFIRE_SEARCH);
25+
} else if (ModRecipes.FURNACE_T1_TYPE.equals(type)) {
26+
cir.setReturnValue(ModRecipeDisplay.FURNACE_T1_SEARCH);
2227
}
2328
}
2429
}

src/main/java/com/tcm/MineTale/block/workbenches/CampfireWorkbench.java

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import com.tcm.MineTale.registry.ModBlockEntities;
1111

1212
import net.minecraft.core.BlockPos;
13-
import net.minecraft.core.Direction;
1413
import net.minecraft.world.level.BlockGetter;
1514
import net.minecraft.world.level.Level;
1615
import net.minecraft.world.level.block.Block;
@@ -19,8 +18,6 @@
1918
import net.minecraft.world.level.block.entity.BlockEntityTicker;
2019
import net.minecraft.world.level.block.entity.BlockEntityType;
2120
import net.minecraft.world.level.block.state.BlockState;
22-
import net.minecraft.world.level.block.state.properties.ChestType;
23-
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf;
2421
import net.minecraft.world.phys.shapes.CollisionContext;
2522
import net.minecraft.world.phys.shapes.VoxelShape;
2623

@@ -114,19 +111,20 @@ public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
114111
return super.newBlockEntity(pos, state);
115112
}
116113

117-
/**
118-
* Compute the master (base) block position for this block based on its state.
119-
*
120-
* @param state the block state of the current block
121-
* @param pos the position of the current block
122-
* @return the position of the master (base) block: if the block is the upper half, the block below is used; if the block's type is `RIGHT`, the position is offset one block counterclockwise from its facing direction; otherwise the original position
123-
*/
124-
public BlockPos getMasterPos(BlockState state, BlockPos pos) {
125-
BlockPos master = pos;
126-
Direction facing = state.getValue(FACING);
127-
if (state.getValue(HALF) == DoubleBlockHalf.UPPER) master = master.below();
128-
if (state.getValue(TYPE) == ChestType.RIGHT) master = master.relative(facing.getCounterClockWise());
129-
return master;
130-
}
114+
// TODO: Check if we need this
115+
// /**
116+
// * Compute the master (base) block position for this block based on its state.
117+
// *
118+
// * @param state the block state of the current block
119+
// * @param pos the position of the current block
120+
// * @return the position of the master (base) block: if the block is the upper half, the block below is used; if the block's type is `RIGHT`, the position is offset one block counterclockwise from its facing direction; otherwise the original position
121+
// */
122+
// public BlockPos getMasterPos(BlockState state, BlockPos pos) {
123+
// BlockPos master = pos;
124+
// Direction facing = state.getValue(FACING);
125+
// if (state.getValue(HALF) == DoubleBlockHalf.UPPER) master = master.below();
126+
// if (state.getValue(TYPE) == ChestType.RIGHT) master = master.relative(facing.getCounterClockWise());
127+
// return master;
128+
// }
131129

132130
}

src/main/java/com/tcm/MineTale/block/workbenches/FurnaceWorkbench.java

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -40,27 +40,6 @@ public FurnaceWorkbench(Properties properties, FurnaceTier tier) {
4040
super(properties, () -> ModTiers.TIER_MAP.get(tier), IS_WIDE, IS_TALL, tier.id());
4141
}
4242

43-
// /**
44-
// * Creates a FurnaceWorkbench that uses a custom BlockEntityType supplier and a 2x2 footprint.
45-
// *
46-
// * @param properties block properties for this workbench
47-
// * @param supplier supplies the BlockEntityType to use for the workbench's master block entity
48-
// */
49-
// public FurnaceWorkbench(Properties properties, Supplier<BlockEntityType<? extends FurnaceWorkbenchEntity>> supplier) {
50-
// super(properties, supplier, IS_WIDE, IS_TALL, 1);
51-
// }
52-
53-
/**
54-
* Ensures the block is rendered using its model so the 2x2 workbench model is visible.
55-
*
56-
* @return {@code RenderShape.MODEL} to render the block with its model
57-
*/
58-
@Override
59-
public RenderShape getRenderShape(BlockState state) {
60-
// Essential so that the 2x2 model is visible
61-
return RenderShape.MODEL;
62-
}
63-
6443
/**
6544
* Provides a ticker that drives furnace workbench logic for the master block.
6645
*
@@ -87,14 +66,39 @@ public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, Block
8766
});
8867
}
8968

90-
/**
91-
* Supply the codec used to serialize and deserialize this FurnaceWorkbench.
69+
/**
70+
* The codec used to serialize and deserialize this CampfireWorkbench type.
9271
*
93-
* @return the MapCodec for this FurnaceWorkbench
72+
* @return the MapCodec for this CampfireWorkbench
9473
*/
9574
@Override
9675
protected MapCodec<? extends FurnaceWorkbench> codec() {
9776
return CODEC;
9877
}
99-
78+
79+
/**
80+
* Ensures the block is rendered using its model so the 2x2 workbench model is visible.
81+
*
82+
* @return {@code RenderShape.MODEL} to render the block with its model
83+
*/
84+
@Override
85+
public RenderShape getRenderShape(BlockState state) {
86+
// Essential so that the 2x2 model is visible
87+
return RenderShape.MODEL;
88+
}
89+
90+
/**
91+
* Create a block entity for the master block of this workbench.
92+
*
93+
* Only the master block of the multi-block workbench receives an entity; other positions return {@code null}.
94+
*
95+
* @return the block entity for the master block ({@link FurnaceWorkbenchEntity}), or {@code null} if this position does not host an entity
96+
*/
97+
@Nullable
98+
@Override
99+
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
100+
// AbstractWorkbench logic ensures only the Master block gets the entity.
101+
// We override it here to point specifically to our Furnace entity.
102+
return super.newBlockEntity(pos, state);
103+
}
100104
}

src/main/java/com/tcm/MineTale/block/workbenches/entity/AbstractFurnaceWorkbenchEntity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ protected void loadAdditional(ValueInput valueInput) {
194194

195195
@Override
196196
public RecipeType<WorkbenchRecipe> getWorkbenchRecipeType() {
197-
return ModRecipes.FURNACE_TYPE;
197+
return ModRecipes.FURNACE_T1_TYPE;
198198
}
199199

200200
@Override

src/main/java/com/tcm/MineTale/block/workbenches/entity/CampfireWorkbenchEntity.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,33 @@ public CampfireWorkbenchEntity(BlockPos blockPos, BlockState blockState) {
103103
*/
104104
public void tick(Level level, BlockPos pos, BlockState state) {
105105
if (level.isClientSide()) return;
106+
107+
boolean changed = false;
108+
109+
// 1. Shift queue forward so the next item is ready to smelt
110+
if (shiftQueueForward()) {
111+
changed = true;
112+
}
113+
}
114+
115+
/**
116+
* Iterates through the queue range. If a slot is empty, it pulls the item
117+
* from the slot behind it.
118+
*/
119+
private boolean shiftQueueForward() {
120+
boolean moved = false;
121+
// Start from the front and pull from the back
122+
for (int i = Constants.INPUT_START; i < Constants.INPUT_START + 1; i++) {
123+
ItemStack current = inventory.getItem(i);
124+
ItemStack next = inventory.getItem(i + 1);
125+
126+
if (current.isEmpty() && !next.isEmpty()) {
127+
inventory.setItem(i, next.copy());
128+
inventory.setItem(i + 1, ItemStack.EMPTY);
129+
moved = true;
130+
}
131+
}
132+
return moved;
106133
}
107134

108135
/**

0 commit comments

Comments
 (0)