diff --git a/patches/minecraft/net/minecraft/world/item/AxeItem.java.patch b/patches/minecraft/net/minecraft/world/item/AxeItem.java.patch index 8ed3f3545e..de0db5a26e 100644 --- a/patches/minecraft/net/minecraft/world/item/AxeItem.java.patch +++ b/patches/minecraft/net/minecraft/world/item/AxeItem.java.patch @@ -10,7 +10,7 @@ if (optional.isEmpty()) { return InteractionResult.PASS; } else { -@@ -103,5 +_,16 @@ +@@ -103,5 +_,21 @@ private Optional getStripped(BlockState p_150691_) { return Optional.ofNullable(STRIPPABLES.get(p_150691_.getBlock())) .map(p_150689_ -> p_150689_.defaultBlockState().setValue(RotatedPillarBlock.AXIS, p_150691_.getValue(RotatedPillarBlock.AXIS))); @@ -25,5 +25,10 @@ + public static BlockState getAxeStrippingState(BlockState originalState) { + Block block = STRIPPABLES.get(originalState.getBlock()); + return block != null ? block.defaultBlockState().setValue(RotatedPillarBlock.AXIS, originalState.getValue(RotatedPillarBlock.AXIS)) : null; ++ } ++ ++ @Override ++ public boolean canDisableShield(ItemStack stack, ItemStack shield, LivingEntity entity, LivingEntity attacker) { ++ return true; } } diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeItem.java b/src/main/java/net/minecraftforge/common/extensions/IForgeItem.java index 30de58cd20..20c1df15be 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeItem.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeItem.java @@ -499,7 +499,7 @@ public interface IForgeItem { * @return True if this ItemStack can disable the shield in question. */ default boolean canDisableShield(ItemStack stack, ItemStack shield, LivingEntity entity, LivingEntity attacker) { - return this instanceof AxeItem; + return attacker.canDisableShield(); } /** diff --git a/src/test/java/net/minecraftforge/debug/gameplay/item/ShieldDisablingTest.java b/src/test/java/net/minecraftforge/debug/gameplay/item/ShieldDisablingTest.java new file mode 100644 index 0000000000..3efde936b9 --- /dev/null +++ b/src/test/java/net/minecraftforge/debug/gameplay/item/ShieldDisablingTest.java @@ -0,0 +1,71 @@ +package net.minecraftforge.debug.gameplay.item; + +import net.minecraft.Util; +import net.minecraft.commands.arguments.EntityAnchorArgument; +import net.minecraft.core.BlockPos; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.GameType; +import net.minecraftforge.event.entity.living.LivingEntityUseItemEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.minecraftforge.gametest.GameTestHolder; +import net.minecraftforge.test.BaseTestMod; + +import java.util.function.Function; + +@Mod(ShieldDisablingTest.MOD_ID) +@GameTestHolder("forge." + ShieldDisablingTest.MOD_ID) +public final class ShieldDisablingTest extends BaseTestMod { + public static final String MOD_ID = "shield_disabling"; + + public ShieldDisablingTest() { } + + @GameTest(template = "forge:empty3x3x3") + public static void player_shield_disabled_by_axe(GameTestHelper helper) { + player_shield_disabled_common(helper, h -> Util.make( + h.spawnWithNoFreeWill(EntityType.HUSK, new BlockPos(2, 0, 2)), + enemy -> enemy.setItemInHand(InteractionHand.MAIN_HAND, new ItemStack(Items.IRON_AXE)) + )); + } + + @GameTest(template = "forge:empty3x3x3") + public static void player_shield_disabled_by_warden(GameTestHelper helper) { + player_shield_disabled_common(helper, h -> h.spawnWithNoFreeWill(EntityType.WARDEN, new BlockPos(2, 0, 2))); + } + + private static void player_shield_disabled_common(GameTestHelper helper, Function enemyGetter) { + helper.makeFloor(); + + // setup player + var player = helper.makeMockPlayer(GameType.SURVIVAL); + helper.addEventListener(event -> { + // Artificially pass 5 seconds from start of the shield + // This is because the first 5 ticks, the player is still vulnerable + if (event.getEntity() == player) { + event.setDuration(event.getDuration() - 100); + } + }); + + // start using shield + var shield = Items.SHIELD.getDefaultInstance(); + player.setItemInHand(InteractionHand.MAIN_HAND, shield); + player.startUsingItem(InteractionHand.MAIN_HAND); + + // setup enemy + var enemy = enemyGetter.apply(helper); + player.lookAt(EntityAnchorArgument.Anchor.EYES, enemy.position()); + + // hit the player + player.hurt(enemy.damageSources().mobAttack(enemy), 5.0F); + + // shield on cooldown? + helper.assertTrue(player.getCooldowns().isOnCooldown(shield.getItem()), "shield should be on cooldown"); + helper.succeed(); + } +}