diff --git a/common/src/main/java/dev/architectury/hooks/item/tool/AxeItemHooks.java b/common/src/main/java/dev/architectury/hooks/item/tool/AxeItemHooks.java new file mode 100644 index 00000000..5a291e09 --- /dev/null +++ b/common/src/main/java/dev/architectury/hooks/item/tool/AxeItemHooks.java @@ -0,0 +1,37 @@ +package dev.architectury.hooks.item.tool; + +import com.google.common.collect.ImmutableMap; +import net.minecraft.world.item.AxeItem; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.RotatedPillarBlock; + +import java.util.HashMap; + +public final class AxeItemHooks { + private AxeItemHooks() { + } + + /** + * Adds a new stripping (interact with axe) interaction to the game.

+ * + * Note that both the input block and the result block must have the + * {@link net.minecraft.world.level.block.state.properties.BlockStateProperties#AXIS AXIS} property, + * and that the value of this property will be copied from the input block to the result block when the recipe + * is performed. + * + * @param input input block + * @param result result block + * @throws IllegalArgumentException if the input or result blocks do not have the + * {@link net.minecraft.world.level.block.state.properties.BlockStateProperties#AXIS AXIS} property. + */ + public static void addStrippable(Block input, Block result) { + if (!input.defaultBlockState().hasProperty(RotatedPillarBlock.AXIS)) + throw new IllegalArgumentException("Input block is missing required 'AXIS' property!"); + if (!result.defaultBlockState().hasProperty(RotatedPillarBlock.AXIS)) + throw new IllegalArgumentException("Result block is missing required 'AXIS' property!"); + if (AxeItem.STRIPPABLES instanceof ImmutableMap) { + AxeItem.STRIPPABLES = new HashMap<>(AxeItem.STRIPPABLES); + } + AxeItem.STRIPPABLES.put(input, result); + } +} diff --git a/common/src/main/java/dev/architectury/hooks/item/tool/HoeItemHooks.java b/common/src/main/java/dev/architectury/hooks/item/tool/HoeItemHooks.java new file mode 100644 index 00000000..ef2f0468 --- /dev/null +++ b/common/src/main/java/dev/architectury/hooks/item/tool/HoeItemHooks.java @@ -0,0 +1,38 @@ +package dev.architectury.hooks.item.tool; + +import com.google.common.collect.ImmutableMap; +import com.mojang.datafixers.util.Pair; +import net.minecraft.world.item.HoeItem; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.block.Block; + +import java.util.HashMap; +import java.util.function.Consumer; +import java.util.function.Predicate; + +public final class HoeItemHooks { + private HoeItemHooks() { + } + + /** + * Adds a new tilling (interact with hoe) interaction to the game.

+ * + * Tilling uses a predicate/consumer pair system: + *

+ * + * @param input input block + * @param predicate context predicate + * @param action action to run + */ + public static void addTillable(Block input, Predicate predicate, Consumer action) { + if (HoeItem.TILLABLES instanceof ImmutableMap) { + HoeItem.TILLABLES = new HashMap<>(HoeItem.TILLABLES); + } + HoeItem.TILLABLES.put(input, new Pair<>(predicate, action)); + } +} diff --git a/common/src/main/java/dev/architectury/hooks/item/tool/ShovelItemHooks.java b/common/src/main/java/dev/architectury/hooks/item/tool/ShovelItemHooks.java new file mode 100644 index 00000000..b709b339 --- /dev/null +++ b/common/src/main/java/dev/architectury/hooks/item/tool/ShovelItemHooks.java @@ -0,0 +1,33 @@ +package dev.architectury.hooks.item.tool; + +import com.google.common.collect.ImmutableMap; +import net.minecraft.world.item.ShovelItem; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.HashMap; + +public final class ShovelItemHooks { + private ShovelItemHooks() { + } + + /** + * Adds a new flattening (interact with shovel) interaction to the game.

+ * + * Notes: + *

+ * + * @param input input block + * @param result result block state + */ + public static void addFlattenable(Block input, BlockState result) { + if (ShovelItem.FLATTENABLES instanceof ImmutableMap) { + ShovelItem.FLATTENABLES = new HashMap<>(ShovelItem.FLATTENABLES); + } + ShovelItem.FLATTENABLES.put(input, result); + } +} diff --git a/common/src/main/resources/architectury.accessWidener b/common/src/main/resources/architectury.accessWidener index 9376d749..c20dffd6 100644 --- a/common/src/main/resources/architectury.accessWidener +++ b/common/src/main/resources/architectury.accessWidener @@ -40,4 +40,10 @@ mutable field net/minecraft/world/level/biome/BiomeSpecialEffects ambientAdditio accessible field net/minecraft/world/level/biome/BiomeSpecialEffects backgroundMusic Ljava/util/Optional; mutable field net/minecraft/world/level/biome/BiomeSpecialEffects backgroundMusic Ljava/util/Optional; accessible method net/minecraft/world/level/storage/LevelResource (Ljava/lang/String;)V -accessible class net/minecraft/world/level/block/entity/BlockEntityType$BlockEntitySupplier \ No newline at end of file +accessible class net/minecraft/world/level/block/entity/BlockEntityType$BlockEntitySupplier +accessible field net/minecraft/world/item/AxeItem STRIPPABLES Ljava/util/Map; +mutable field net/minecraft/world/item/AxeItem STRIPPABLES Ljava/util/Map; +accessible field net/minecraft/world/item/ShovelItem FLATTENABLES Ljava/util/Map; +mutable field net/minecraft/world/item/ShovelItem FLATTENABLES Ljava/util/Map; +accessible field net/minecraft/world/item/HoeItem TILLABLES Ljava/util/Map; +mutable field net/minecraft/world/item/HoeItem TILLABLES Ljava/util/Map; \ No newline at end of file diff --git a/fabric/src/main/resources/architectury.accessWidener b/fabric/src/main/resources/architectury.accessWidener index 5e44d25c..dd39e916 100644 --- a/fabric/src/main/resources/architectury.accessWidener +++ b/fabric/src/main/resources/architectury.accessWidener @@ -98,4 +98,10 @@ mutable field net/minecraft/world/level/biome/BiomeSpecialEffects ambientAdditio accessible field net/minecraft/world/level/biome/BiomeSpecialEffects backgroundMusic Ljava/util/Optional; mutable field net/minecraft/world/level/biome/BiomeSpecialEffects backgroundMusic Ljava/util/Optional; accessible method net/minecraft/world/level/storage/LevelResource (Ljava/lang/String;)V -accessible class net/minecraft/world/level/block/entity/BlockEntityType$BlockEntitySupplier \ No newline at end of file +accessible class net/minecraft/world/level/block/entity/BlockEntityType$BlockEntitySupplier +accessible field net/minecraft/world/item/AxeItem STRIPPABLES Ljava/util/Map; +mutable field net/minecraft/world/item/AxeItem STRIPPABLES Ljava/util/Map; +accessible field net/minecraft/world/item/ShovelItem FLATTENABLES Ljava/util/Map; +mutable field net/minecraft/world/item/ShovelItem FLATTENABLES Ljava/util/Map; +accessible field net/minecraft/world/item/HoeItem TILLABLES Ljava/util/Map; +mutable field net/minecraft/world/item/HoeItem TILLABLES Ljava/util/Map; \ No newline at end of file diff --git a/forge/src/main/resources/META-INF/accesstransformer.cfg b/forge/src/main/resources/META-INF/accesstransformer.cfg index 2cbec00e..a18e70b5 100644 --- a/forge/src/main/resources/META-INF/accesstransformer.cfg +++ b/forge/src/main/resources/META-INF/accesstransformer.cfg @@ -45,3 +45,6 @@ public net.minecraft.world.level.GameRules$IntegerValue m_46294_(ILjava/util/fun public net.minecraft.client.particle.ParticleEngine f_107296_ # textureAtlas public net.minecraft.client.particle.ParticleEngine$MutableSpriteSet public net.minecraft.client.particle.ParticleEngine$MutableSpriteSet f_107406_ # sprites +public-f net.minecraft.world.item.AxeItem f_150683_ # STRIPPABLES +public-f net.minecraft.world.item.ShovelItem f_43110_ # FLATTENABLES +public-f net.minecraft.world.item.HoeItem f_41332_ # TILLABLES diff --git a/gradle.properties b/gradle.properties index ac1bf7d6..61be9db0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ cf_type=release archives_base_name=architectury archives_base_name_snapshot=architectury-snapshot -base_version=2.3 +base_version=2.4 maven_group=dev.architectury fabric_loader_version=0.11.6 diff --git a/testmod-common/src/main/java/dev/architectury/test/TestMod.java b/testmod-common/src/main/java/dev/architectury/test/TestMod.java index bdc91ad1..03ce539d 100644 --- a/testmod-common/src/main/java/dev/architectury/test/TestMod.java +++ b/testmod-common/src/main/java/dev/architectury/test/TestMod.java @@ -29,6 +29,7 @@ import dev.architectury.test.events.DebugEvents; import dev.architectury.test.gamerule.TestGameRules; import dev.architectury.test.networking.TestModNet; import dev.architectury.test.particle.TestParticles; +import dev.architectury.test.item.TestBlockInteractions; import dev.architectury.test.registry.TestRegistries; import dev.architectury.test.registry.client.TestKeybinds; import dev.architectury.test.tags.TestTags; @@ -52,6 +53,7 @@ public class TestMod { TestTrades.init(); TestParticles.initialize(); TestModNet.initialize(); + TestBlockInteractions.init(); if (Platform.getEnvironment() == Env.CLIENT) { initializeClient(); } diff --git a/testmod-common/src/main/java/dev/architectury/test/item/TestBlockInteractions.java b/testmod-common/src/main/java/dev/architectury/test/item/TestBlockInteractions.java new file mode 100644 index 00000000..18150e79 --- /dev/null +++ b/testmod-common/src/main/java/dev/architectury/test/item/TestBlockInteractions.java @@ -0,0 +1,39 @@ +package dev.architectury.test.item; + +import dev.architectury.hooks.item.tool.AxeItemHooks; +import dev.architectury.hooks.item.tool.HoeItemHooks; +import dev.architectury.hooks.item.tool.ShovelItemHooks; +import net.minecraft.Util; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.block.Blocks; + +public final class TestBlockInteractions { + private TestBlockInteractions() { + } + + public static void init() { + AxeItemHooks.addStrippable(Blocks.QUARTZ_PILLAR, Blocks.OAK_LOG); + ShovelItemHooks.addFlattenable(Blocks.IRON_ORE, Blocks.DIAMOND_BLOCK.defaultBlockState()); + HoeItemHooks.addTillable(Blocks.COAL_BLOCK, ctx -> { + if (!ctx.getLevel().isNight()) { + if (!ctx.getLevel().isClientSide) { + Player player = ctx.getPlayer(); + if (player != null) + player.sendMessage(new TextComponent("These dark arts can only be done at night!"), Util.NIL_UUID); + } + return false; + } + return true; + }, ctx -> { + BlockPos pos = ctx.getClickedPos(); + ctx.getLevel().setBlock(pos, Blocks.DIAMOND_BLOCK.defaultBlockState(), 3); + if (!ctx.getLevel().isClientSide) { + Player player = ctx.getPlayer(); + if (player != null) + player.sendMessage(new TextComponent("Thou has successfully committed the dark arts of alchemy!!"), Util.NIL_UUID); + } + }); + } +}