Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@
import java.util.stream.Collectors;

import com.tcm.MineTale.MineTale;
import com.tcm.MineTale.block.workbenches.entity.AbstractWorkbenchEntity;
import com.tcm.MineTale.block.workbenches.menu.AbstractWorkbenchContainerMenu;
import com.tcm.MineTale.block.workbenches.menu.WorkbenchWorkbenchMenu;
import com.tcm.MineTale.mixin.client.ClientRecipeBookAccessor;
import com.tcm.MineTale.mixin.client.RecipeBookComponentAccessor;
import com.tcm.MineTale.network.CraftRequestPayload;
import com.tcm.MineTale.recipe.MineTaleRecipeBookComponent;
import com.tcm.MineTale.recipe.WorkbenchRecipe;
import com.tcm.MineTale.registry.ModBlocks;
import com.tcm.MineTale.registry.ModRecipeDisplay;
import com.tcm.MineTale.registry.ModRecipes;
Expand All @@ -30,7 +28,6 @@
import net.minecraft.client.renderer.RenderPipelines;
import net.minecraft.core.HolderSet;
import net.minecraft.resources.Identifier;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
Expand Down Expand Up @@ -211,6 +208,14 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
renderTooltip(graphics, mouseX, mouseY);
}

/**
* Determines whether the player has enough ingredients to craft the given recipe the specified number of times.
*
* @param player the player whose inventory (and networked nearby items) will be checked; may be null
* @param entry the recipe display entry providing crafting requirements; may be null
* @param craftCount the multiplier for required ingredient quantities (e.g., 1, 10, or -1 is not specially handled here)
* @return `true` if the player has at least the required quantity of each ingredient multiplied by `craftCount`, `false` otherwise (also returns `false` if `player` or `entry` is null or the recipe has no requirements)
*/
private boolean canCraft(Player player, RecipeDisplayEntry entry, int craftCount) {
if (player == null || entry == null) return false;

Expand All @@ -231,6 +236,7 @@ private boolean canCraft(Player player, RecipeDisplayEntry entry, int craftCount
// IF we use a helper that handles the hashing correctly.

// Strategy: Use the stream of holders as a List key (Lists have stable hashcodes)
@SuppressWarnings("deprecation")
HolderSet<Item> key = ing.items().collect(Collectors.collectingAndThen(Collectors.toList(), HolderSet::direct));
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

aggregatedRequirements.put(key, aggregatedRequirements.getOrDefault(key, 0) + 1);
Expand Down
59 changes: 29 additions & 30 deletions src/client/java/com/tcm/MineTale/datagen/ModModelProvider.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
package com.tcm.MineTale.datagen;

import com.tcm.MineTale.MineTale;
import com.tcm.MineTale.registry.ModBlocks;
import net.fabricmc.fabric.api.client.datagen.v1.provider.FabricModelProvider;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.minecraft.client.data.models.BlockModelGenerators;
import net.minecraft.client.data.models.ItemModelGenerators;
import net.minecraft.client.data.models.blockstates.MultiVariantGenerator;
import net.minecraft.client.data.models.blockstates.PropertyDispatch;
import net.minecraft.client.data.models.model.ModelLocationUtils;
import net.minecraft.client.renderer.block.model.VariantMutator;
import net.minecraft.core.Direction;
import net.minecraft.resources.Identifier;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.ChestType;
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf;

public class ModModelProvider extends FabricModelProvider {
Expand All @@ -32,12 +31,12 @@ public class ModModelProvider extends FabricModelProvider {
.select(Direction.WEST, BlockModelGenerators.Y_ROT_270);

/**
* Registers block state and model definitions for the mod's log blocks.
* Registers block state and model definitions for the mod's custom log blocks and furnace workbenches.
*
* This configures horizontal and vertical log models for each custom log block and, for
* WILD_WISTERIA_LOG, also registers the corresponding wood model (WILD_WISTERIA_WOOD).
* Configures horizontal and vertical variants for each custom log block and registers the wood model for
* WILD_WISTERIA_LOG; registers blockstate variants and item models for the mod's furnace workbench blocks.
*
* @param blockStateModelGenerator the generator used to create block state and model entries
* @param blockStateModelGenerator generator used to create block state and model entries
*/
@Override
public void generateBlockStateModels(BlockModelGenerators blockStateModelGenerator) {
Expand Down Expand Up @@ -72,38 +71,38 @@ public void generateBlockStateModels(BlockModelGenerators blockStateModelGenerat
blockStateModelGenerator.woodProvider(ModBlocks.WINDWILLOW_LOG).logWithHorizontal(ModBlocks.WINDWILLOW_LOG);
blockStateModelGenerator.woodProvider(ModBlocks.WILD_WISTERIA_LOG).logWithHorizontal(ModBlocks.WILD_WISTERIA_LOG).wood(ModBlocks.WILD_WISTERIA_WOOD);

registerLargeWorkbench(blockStateModelGenerator, ModBlocks.FURNACE_WORKBENCH_BLOCK_T1);
registerLargeWorkbench(blockStateModelGenerator, ModBlocks.FURNACE_WORKBENCH_BLOCK_T2);
registerFurnaceWorkbench(blockStateModelGenerator, ModBlocks.FURNACE_WORKBENCH_BLOCK_T1);
registerFurnaceWorkbench(blockStateModelGenerator, ModBlocks.FURNACE_WORKBENCH_BLOCK_T2);
}

private void registerLargeWorkbench(BlockModelGenerators generator, Block block) {
// 1. Get the base identifier (e.g., minetale:block/furnace_workbench_block_t1)
Identifier blockId = ModelLocationUtils.getModelLocation(block);

// 2. Build the references to your manual JSON files
// .withSuffix() creates: minetale:block/furnace_workbench_block_t1_bottom_left, etc.
Identifier bottomLeft = blockId.withSuffix("_bottom_left");
Identifier bottomRight = blockId.withSuffix("_bottom_right");
Identifier topLeft = blockId.withSuffix("_top_left");
Identifier topRight = blockId.withSuffix("_top_right");
Identifier inventory = blockId.withSuffix("_inventory");
/**
* Registers block state variants and the item model for a two-block furnace workbench.
*
* Uses explicit shared model identifiers for the top, bottom, and inventory models, dispatches
* the block state by `DOUBLE_BLOCK_HALF` to select the top or bottom model, applies
* `WORKBENCH_ROTATION` for horizontal orientation, and registers the simple item model.
*
* @param generator the BlockModelGenerators instance used to emit blockstate and item model data
* @param block the furnace workbench block to register models for
*/
private void registerFurnaceWorkbench(BlockModelGenerators generator, Block block) {
// 1. Manually define the shared model paths
// Path: assets/minetale/models/block/bench/furnace_top.json
Identifier topModel = Identifier.fromNamespaceAndPath(MineTale.MOD_ID, "block/bench/furnace_top");
Identifier bottomModel = Identifier.fromNamespaceAndPath(MineTale.MOD_ID, "block/bench/furnace_bottom");
Identifier inventoryModel = Identifier.fromNamespaceAndPath(MineTale.MOD_ID, "block/bench/furnace_inventory");

// 3. Dispatch to Blockstate (Tells the game which model to show for each state)
// 4. Dispatch to Blockstate
generator.blockStateOutput.accept(MultiVariantGenerator.dispatch(block)
.with(PropertyDispatch.initial(BlockStateProperties.DOUBLE_BLOCK_HALF, BlockStateProperties.CHEST_TYPE)
.select(DoubleBlockHalf.LOWER, ChestType.LEFT, BlockModelGenerators.plainVariant(bottomLeft))
.select(DoubleBlockHalf.LOWER, ChestType.RIGHT, BlockModelGenerators.plainVariant(bottomRight))
.select(DoubleBlockHalf.UPPER, ChestType.LEFT, BlockModelGenerators.plainVariant(topLeft))
.select(DoubleBlockHalf.UPPER, ChestType.RIGHT, BlockModelGenerators.plainVariant(topRight))
// Support the 'SINGLE' state as a fallback
.select(DoubleBlockHalf.LOWER, ChestType.SINGLE, BlockModelGenerators.plainVariant(bottomLeft))
.select(DoubleBlockHalf.UPPER, ChestType.SINGLE, BlockModelGenerators.plainVariant(topLeft))
.with(PropertyDispatch.initial(BlockStateProperties.DOUBLE_BLOCK_HALF)
.select(DoubleBlockHalf.LOWER, BlockModelGenerators.plainVariant(bottomModel))
.select(DoubleBlockHalf.UPPER, BlockModelGenerators.plainVariant(topModel))
)
.with(WORKBENCH_ROTATION)
);
Comment thread
coderabbitai[bot] marked this conversation as resolved.

// 4. Map the Item in your hand to the inventory JSON
generator.registerSimpleItemModel(block, inventory);
// 5. Register the Item Model
generator.registerSimpleItemModel(block, inventoryModel);
Comment thread
The-Code-Monkey marked this conversation as resolved.
}

/**
Expand Down
1 change: 0 additions & 1 deletion src/main/java/com/tcm/MineTale/MineTale.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import static com.tcm.MineTale.item.ModCreativeTab.MINETALE_CREATIVE_TAB;
import static com.tcm.MineTale.item.ModCreativeTab.MINETALE_CREATIVE_TAB_KEY;

import java.util.List;
import java.util.Optional;

public class MineTale implements ModInitializer {
Expand Down
Loading