Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 3 additions & 3 deletions src/client/java/com/tcm/MineTale/MineTaleDataGen.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
public class MineTaleDataGen implements DataGeneratorEntrypoint {

/**
* Initialize a data pack and register the mod's data providers.
* Initialize a data pack and register the mod's data providers for data generation.
*
* Creates a data pack from the given Fabric data generator and adds the language
* and model providers so they will run during data generation.
* Registers language, model, recipe, block tag, and loot table providers so they
* will run as part of the Fabric data generation pack created from the given generator.
*
* @param fabricDataGenerator the Fabric data generator used to create the data pack
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ public ModBlockTagProvider(FabricDataOutput output, CompletableFuture<HolderLook
}

/**
* Populates the BlockTags.LOGS tag with this mod's log blocks.
* Populate block tags with this mod's blocks.
*
* Registers each mod-defined log block so they are included in the game's LOGS tag mapping.
* Adds mod-defined blocks to relevant vanilla block tags (for example
* MINEABLE_WITH_PICKAXE, MINEABLE_WITH_AXE, and LOGS) so they are included
* in the game's tag mappings.
*
* @param provider a registry lookup provider used to resolve holders during tag population
* @param provider registry lookup provider used to resolve holders during tag population
*/
@Override
protected void addTags(HolderLookup.Provider provider) {
Expand Down
46 changes: 42 additions & 4 deletions src/client/java/com/tcm/MineTale/datagen/ModLootTableProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,25 @@
import java.util.concurrent.CompletableFuture;

public class ModLootTableProvider extends FabricBlockLootTableProvider {
/**
* Creates a ModLootTableProvider used to generate the mod's block loot tables.
*
* Initializes the provider with the data output target and a future registry lookup used to resolve game registries during loot table generation.
*
* @param dataOutput the data output target for generated data
* @param registryLookup a future that provides a HolderLookup.Provider for resolving registries needed while generating loot tables
*/
public ModLootTableProvider(FabricDataOutput dataOutput, CompletableFuture<HolderLookup.Provider> registryLookup) {
super(dataOutput, registryLookup);
}

/**
* Registers loot tables for the mod's workbench blocks.
*
* Each added loot table causes the block to drop itself (one item) only when the block's state
* matches the required DoubleBlockHalf (LOWER) and ChestType (LEFT or SINGLE) for that block,
* and the drop is subject to explosion survival/decay.
*/
@Override
public void generate() {
///Block Drops Itself
Expand Down Expand Up @@ -113,27 +128,50 @@ public void generate() {


/// For Ore Drops
/** Ex:
* add(ModBlocks.IRON_ORE_SHALE, AverageOreDrops(ModBlocks.IRON_ORE_SHALE, Items.RAW_IRON));
* **/
/**
* Create a loot table builder that drops the specified item in multiple quantities with Silk Touch, Fortune bonus, and explosion decay applied.
*
* @param drop the source block used for Silk Touch dispatch and explosion-decay context
* @param item the item to drop from the ore
* @return a LootTable.Builder that drops `item` in a base count between 2 and 5, augmented by the Fortune enchantment, with Silk Touch handling and explosion decay applied
*/
public LootTable.Builder AverageOreDrops(Block drop, Item item) {
HolderLookup.RegistryLookup<Enchantment> impl = this.registries.lookupOrThrow(Registries.ENCHANTMENT);
return this.createSilkTouchDispatchTable(drop, this.applyExplosionDecay(drop, ((LootPoolSingletonContainer.Builder<?>)
LootItem.lootTableItem(item).apply(SetItemCountFunction.setCount(UniformGenerator.between(2, 5))))
.apply(ApplyBonusCount.addOreBonusCount(impl.getOrThrow(Enchantments.FORTUNE)))));
}

/**
* Creates a loot table builder for an ore that yields the specified item with Silk Touch and Fortune handling.
*
* The table gives a base drop count of exactly 1 (before Fortune), increases the count with Fortune, returns the
* ore block when mined with Silk Touch, and applies explosion decay to the drop.
*
* @param drop the ore block (returned when Silk Touch is used)
* @param item the item to drop when the ore is mined without Silk Touch
* @return a LootTable.Builder configured to drop the specified item with Fortune bonuses, Silk Touch dispatch,
* and explosion decay
*/
public LootTable.Builder SingleOreDrops(Block drop, Item item) {
HolderLookup.RegistryLookup<Enchantment> impl = this.registries.lookupOrThrow(Registries.ENCHANTMENT);
return this.createSilkTouchDispatchTable(drop, this.applyExplosionDecay(drop, ((LootPoolSingletonContainer.Builder<?>)
LootItem.lootTableItem(item).apply(SetItemCountFunction.setCount(ConstantValue.exactly(1))))
.apply(ApplyBonusCount.addOreBonusCount(impl.getOrThrow(Enchantments.FORTUNE)))));
}

/**
* Builds a loot table for a "light" ore block that supports Silk Touch, Fortune bonuses, and explosion decay.
*
* @param drop the ore block whose loot table is being created
* @param item the item to drop from the ore when not Silk Touched
* @return a LootTable.Builder that drops {@code item} in quantities of 1–2 (before Fortune), applies Fortune bonus,
* dispatches to Silk Touch drops when applicable, and respects explosion decay
*/
public LootTable.Builder LightOreDrops(Block drop, Item item) {
HolderLookup.RegistryLookup<Enchantment> impl = this.registries.lookupOrThrow(Registries.ENCHANTMENT);
return this.createSilkTouchDispatchTable(drop, this.applyExplosionDecay(drop, ((LootPoolSingletonContainer.Builder<?>)
LootItem.lootTableItem(item).apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 2))))
.apply(ApplyBonusCount.addOreBonusCount(impl.getOrThrow(Enchantments.FORTUNE)))));
}
}
}
11 changes: 10 additions & 1 deletion src/main/java/com/tcm/MineTale/MineTale.java
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,16 @@ public void onInitialize() {
LOGGER.info("MineTale Loaded!");
}

private boolean hasIngredients(ServerPlayer player, WorkbenchRecipe recipe) {
/**
* Determines whether the player (and nearby pullable chests, if the workbench allows) collectively contain all item ingredients required by the given workbench recipe.
*
* This check requires the player's open container to be an AbstractWorkbenchContainerMenu; if it is not, the method returns `false`. It examines the player's non-equipment inventory and, when the workbench permits pulling, the contents of nearby inventories. Each recipe ingredient must be satisfied by a distinct matching item instance from those inventories.
*
* @param player the server player whose inventories are checked
* @param recipe the workbench recipe whose ingredient requirements are being validated
* @return `true` if all ingredients of the recipe can be satisfied from the player and allowed nearby inventories, `false` otherwise
*/
private boolean hasIngredients(ServerPlayer player, WorkbenchRecipe recipe) {
if (!(player.containerMenu instanceof AbstractWorkbenchContainerMenu menu)) return false;
AbstractWorkbenchEntity be = menu.getBlockEntity();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,24 @@ protected float getShadeBrightness(BlockState state, BlockGetter level, BlockPos
return 1.0F;
}

/**
* Handle teardown of a multi-block workbench when a player destroys one of its parts,
* ensuring the master/slave parts are removed consistently and loot is produced exactly once.
*
* <p>Server-side behavior:
* - Computes the master (bottom-left) position for the workbench and whether the broken part is the master.
* - Iterates the workbench footprint (2x2 if wide and tall, or the corresponding subset) and removes other parts:
* - If the master is broken, other parts are removed silently (no drops).
* - If a slave is broken, the master is destroyed (producing drops unless the player is in creative) and other slaves are removed silently.
* - Emits GameEvent.BLOCK_DESTROY for each part that is removed.
* - If a slave was broken by a non-creative player, prevents the slave part itself from dropping to avoid duplicate loot.
*
* @param level the world where the destruction occurs
* @param pos the position of the part being destroyed
* @param state the block state of the part being destroyed (may be modified to suppress drops)
* @param player the player performing the destruction
* @return the BlockState returned by the superclass implementation after custom teardown handling
*/
@Override
public BlockState playerWillDestroy(Level level, BlockPos pos, BlockState state, Player player) {
if (!level.isClientSide()) {
Expand Down
12 changes: 11 additions & 1 deletion src/main/java/com/tcm/MineTale/util/ModLootTableModifiers.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ public class ModLootTableModifiers {
private static final Identifier SHORT_GRASS_ID = Identifier.fromNamespaceAndPath("minecraft", "blocks/short_grass");
private static final Identifier TALL_GRASS_ID = Identifier.fromNamespaceAndPath("minecraft", "blocks/tall_grass");

/**
* Registers a listener that modifies the loot tables for short and tall grass.
*
* <p>When the listener sees the short grass loot table, it replaces its pools with a single-roll
* pool that can produce AIR (count exactly 1) and STICK (count between 1 and 3). When the listener
* sees the tall grass loot table, it replaces its pools with a single-roll pool that can produce
* STICK (weight 1, count between 1 and 4).
*
* <p>This method registers the modification via LootTableEvents.MODIFY.
*/
public static void modifyLootTables() {
LootTableEvents.MODIFY.register((key, tableBuilder, sources, registry) -> {
if (SHORT_GRASS_ID.equals(key.identifier())) {
Expand All @@ -34,4 +44,4 @@ public static void modifyLootTables() {
}
});
}
}
}