From a8e10e39b21713d40b8b1a99d08a66962e89b17b Mon Sep 17 00:00:00 2001 From: Arnab Nandy Date: Sun, 9 Aug 2026 15:51:56 +0530 Subject: [PATCH] Fix duplicate door drops Signed-off-by: Arnab Nandy --- CHANGELOG.md | 3 ++- buildSrc/src/main/kotlin/common.gradle.kts | 11 ++++++++- .../tazer/clutternomore/common/CHooks.java | 23 ++++++++++++++++++ .../common/MultiBlockLootPart.java | 9 +++++++ .../clutternomore/common/CHooksTest.java | 24 +++++++++++++++++++ 5 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 src/main/java/dev/tazer/clutternomore/common/MultiBlockLootPart.java create mode 100644 src/test/java/dev/tazer/clutternomore/common/CHooksTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b6b696..208c491 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,4 +4,5 @@ - Fixed compatibility issue with Enchancement caused by mixins not chaining. - Fixed `/reload` breaking some functionality. - Fixed lang overrides not being respected in some cases. -- Added some config options to revert the loot table and recipe changes by the mod. \ No newline at end of file +- Added some config options to revert the loot table and recipe changes by the mod. +- Fixed mapped doors dropping duplicate items when broken. diff --git a/buildSrc/src/main/kotlin/common.gradle.kts b/buildSrc/src/main/kotlin/common.gradle.kts index 70c3505..c498574 100644 --- a/buildSrc/src/main/kotlin/common.gradle.kts +++ b/buildSrc/src/main/kotlin/common.gradle.kts @@ -3,6 +3,15 @@ plugins { idea } +dependencies { + testImplementation("org.junit.jupiter:junit-jupiter:5.11.4") + testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.11.4") +} + +tasks.test { + useJUnitPlatform() +} + version = "${prop("mod.version")}+${dep("minecraft")}-$loaderName" base.archivesName = prop("mod.id") @@ -75,4 +84,4 @@ stonecutterBuild.replacements.string { stonecutterBuild.replacements.string { direction = stonecutterBuild.eval(mc, ">1.21.2") replace("DirectionProperty", "EnumProperty") -} \ No newline at end of file +} diff --git a/src/main/java/dev/tazer/clutternomore/common/CHooks.java b/src/main/java/dev/tazer/clutternomore/common/CHooks.java index 4c5457f..b4dea21 100644 --- a/src/main/java/dev/tazer/clutternomore/common/CHooks.java +++ b/src/main/java/dev/tazer/clutternomore/common/CHooks.java @@ -15,6 +15,7 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.Property; import net.minecraft.world.level.block.state.properties.SlabType; import net.minecraft.world.level.storage.loot.LootParams; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; @@ -36,11 +37,33 @@ public static List getDrops(List old, BlockState state, Se ) { Item item = state.getBlock().asItem(); if (ShapeMap.isShape(item) && ClutterNoMore.STARTUP_CONFIG.INHERIT_LOOT_TABLES.value()) { + if (isNonLowerMultiBlockPart(state)) return old; + LootParams.Builder lootparams$builder = (new LootParams.Builder(level)).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(pos)).withParameter(LootContextParams.TOOL, tool).withOptionalParameter(LootContextParams.THIS_ENTITY, entity).withOptionalParameter(LootContextParams.BLOCK_ENTITY, blockEntity); BlockState newState = Block.byItem(ShapeMap.getParent(item)).defaultBlockState(); + for (Property property : state.getProperties()) { + newState = copyProperty(state, newState, property); + } return newState.getDrops(lootparams$builder); } return old; } + + private static boolean isNonLowerMultiBlockPart(BlockState state) { + for (Property property : state.getProperties()) { + if (MultiBlockLootPart.isNonLower(property.getName(), propertyValueName(state, property))) { + return true; + } + } + return false; + } + + private static > String propertyValueName(BlockState state, Property property) { + return property.getName(state.getValue(property)); + } + + private static > BlockState copyProperty(BlockState source, BlockState target, Property property) { + return target.hasProperty(property) ? target.setValue(property, source.getValue(property)) : target; + } } diff --git a/src/main/java/dev/tazer/clutternomore/common/MultiBlockLootPart.java b/src/main/java/dev/tazer/clutternomore/common/MultiBlockLootPart.java new file mode 100644 index 0000000..1184ace --- /dev/null +++ b/src/main/java/dev/tazer/clutternomore/common/MultiBlockLootPart.java @@ -0,0 +1,9 @@ +package dev.tazer.clutternomore.common; + +final class MultiBlockLootPart { + private MultiBlockLootPart() {} + + static boolean isNonLower(String property, String value) { + return (property.equals("half") || property.equals("third")) && (value.equals("middle") || value.equals("upper")); + } +} diff --git a/src/test/java/dev/tazer/clutternomore/common/CHooksTest.java b/src/test/java/dev/tazer/clutternomore/common/CHooksTest.java new file mode 100644 index 0000000..b1d91a6 --- /dev/null +++ b/src/test/java/dev/tazer/clutternomore/common/CHooksTest.java @@ -0,0 +1,24 @@ +package dev.tazer.clutternomore.common; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class CHooksTest { + @Test + void suppressesOnlyNonLowerMultiBlockParts() { + assertFalse(MultiBlockLootPart.isNonLower("half", "lower")); + assertTrue(MultiBlockLootPart.isNonLower("half", "upper")); + + assertFalse(MultiBlockLootPart.isNonLower("third", "lower")); + assertTrue(MultiBlockLootPart.isNonLower("third", "middle")); + assertTrue(MultiBlockLootPart.isNonLower("third", "upper")); + } + + @Test + void ignoresUnrelatedPropertiesAndValues() { + assertFalse(MultiBlockLootPart.isNonLower("facing", "upper")); + assertFalse(MultiBlockLootPart.isNonLower("half", "top")); + } +}