Re-introduce IForgeItem.damageItem when an item takes damage, Fixes #10344 (#10374)

This commit is contained in:
Jonathing authored and GitHub committed 2025-02-17 19:09:58 -08:00
1 parent 208adc1109
commit b8bbf950a9
7 files changed
+321 -9

No files matched your search

@@ -5,10 +5,14 @@
package net.minecraftforge.common.extensions;
import java.util.Arrays;
import java.util.Objects;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Supplier;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import org.jetbrains.annotations.Nullable;
import com.mojang.authlib.GameProfile;
@@ -60,6 +64,28 @@ public interface IForgeGameTestHelper {
throw new GameTestAssertException(message.get());
}
default <N> void assertValueEqual(N expected, N actual, String name, String message) {
this.assertValueEqual(expected, actual, name, () -> message);
}
default <N> void assertValueEqual(N expected, N actual, String name, Supplier<String> message) {
if (!Objects.equals(expected, actual))
throw new GameTestAssertException("%s -- Expected %s to be %s, but was %s".formatted(message.get(), name, expected, actual));
}
default <N> void assertValueEqual(N[] expected, N[] actual, String name, String message) {
this.assertValueEqual(expected, actual, name, () -> message);
}
default <N> void assertValueEqual(N[] expected, N[] actual, String name, Supplier<String> message) {
if (!Objects.deepEquals(expected, actual))
throw new GameTestAssertException("%s -- Expected %s to be %s, but was %s".formatted(message.get(), name, Arrays.toString(expected), Arrays.toString(actual)));
}
default <E> Registry<E> registryLookup(ResourceKey<? extends Registry<? extends E>> registryKey) {
return this.self().getLevel().registryAccess().lookupOrThrow(registryKey);
}
default ServerPlayer makeMockServerPlayer() {
var level = self().getLevel();
var cookie = CommonListenerCookie.createInitial(new GameProfile(UUID.randomUUID(), "test-mock-player"), false);
@@ -158,19 +184,49 @@ public interface IForgeGameTestHelper {
}
public void assertUnset() {
if (this.value != null)
throw new GameTestAssertException("Expected " + name + " to be null, but was " + this.value);
this.assertUnset((Supplier<String>) null);
}
public void assertUnset(String message) {
this.assertUnset(message != null ? () -> message : null);
}
public void assertUnset(Supplier<String> message) {
if (this.value != null) {
String s = message != null ? message.get() + " -- " : "";
throw new GameTestAssertException(s + "Expected " + name + " to be null, but was " + this.value);
}
}
public void assertSet() {
if (this.value == null)
throw new GameTestAssertException("Flag " + name + " was never set");
this.assertSet((Supplier<String>) null);
}
public void assertSet(String message) {
this.assertSet(message != null ? () -> message : null);
}
public void assertSet(Supplier<String> message) {
if (this.value == null) {
String s = message != null ? message.get() + " -- " : "";
throw new GameTestAssertException(s + "Flag " + name + " was never set");
}
}
public void assertEquals(T expected) {
assertSet();
if (expected != null && !expected.equals(this.value))
throw new GameTestAssertException("Expected " + name + " to be " + expected + ", but was " + this.value);
this.assertEquals(expected, (Supplier<String>) null);
}
public void assertEquals(T expected, String message) {
this.assertEquals(expected, message != null ? () -> message : null);
}
public void assertEquals(T expected, Supplier<String> message) {
assertSet(message);
if (expected != null && !expected.equals(this.value)) {
String s = message != null ? message.get() + " -- " : "";
throw new GameTestAssertException(s + "Expected " + name + " to be " + expected + ", but was " + this.value);
}
}
}
@@ -195,9 +251,29 @@ public interface IForgeGameTestHelper {
return this.value == null ? -1 : this.value.longValue();
}
public void assertEquals(int expected) {
super.assertEquals((long) expected);
}
public void assertEquals(long expected) {
super.assertEquals(expected);
}
public void assertEquals(int expected, String message) {
super.assertEquals((long) expected, message);
}
public void assertEquals(long expected, String message) {
super.assertEquals(expected, message);
}
public void assertEquals(int expected, Supplier<String> message) {
super.assertEquals((long) expected, message);
}
public void assertEquals(long expected, Supplier<String> message) {
super.assertEquals(expected, message);
}
}
public static class BoolFlag extends Flag<Boolean> {
@@ -216,5 +292,13 @@ public interface IForgeGameTestHelper {
public void assertEquals(boolean expected) {
super.assertEquals(expected);
}
public void assertEquals(boolean expected, String message) {
super.assertEquals(expected, message);
}
public void assertEquals(boolean expected, Supplier<String> message) {
super.assertEquals(expected, message);
}
}
}
@@ -7,6 +7,9 @@ package net.minecraftforge.common.extensions;
import java.util.function.Consumer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.RandomSource;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.item.*;
@@ -521,6 +524,25 @@ public interface IForgeItem {
*/
default void onHorseArmorTick(ItemStack stack, Level level, Mob horse) { }
/**
* Called when this item is to be damaged, such as use a tool being used or a shield blocking damage. The damage
* parameter has not yet been processed, so enchantments are not taken into account.
*
* @param stack The processed amount of damage the item will take
* @param damage The amount of damage the item will take before processing
* @param random The random used where the damage is taking place (typically from the level)
* @param player The player holding the item
* @param onBroken The callback for when an item is broken (use this if you plan on cancelling damage that will
* break an item)
* @return The amount of damage the item should take, after processing
*
* @apiNote If the item stack is not {@linkplain ItemStack#isDamageableItem() damageable}, this method will not be
* called.
*/
default int damageItem(ItemStack stack, int damage, RandomSource random, @Nullable ServerPlayer player, Runnable onBroken) {
return damage;
}
/**
* Called when an item entity for this stack is destroyed. Note: The {@link ItemStack} can be retrieved from the item entity.
*
@@ -5,6 +5,9 @@
package net.minecraftforge.common.extensions;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.RandomSource;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.monster.EnderMan;
import net.minecraft.world.entity.player.Inventory;
@@ -31,6 +34,8 @@ import net.minecraftforge.common.ToolActions;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Consumer;
/*
* Extension added to ItemStack that bounces to ItemSack sensitive Item methods. Typically this is just for convince.
*/
@@ -398,6 +403,25 @@ public interface IForgeItemStack {
return self().getItem().getSweepHitBox(self(), player, target);
}
/**
* Called when this item is to be damaged, such as use a tool being used or a shield blocking damage. The damage
* parameter has not yet been processed, so enchantments are not taken into account.
*
* @param damage The amount of damage the item will take before processing
* @param random The random used where the damage is taking place (typically from the level)
* @param player The player holding the item
* @param onBroken The callback for when an item is broken (use this if you plan on cancelling damage that will
* break an item)
* @return The amount of damage the item should take
*
* @apiNote If the item stack is not {@linkplain ItemStack#isDamageableItem() damageable}, this method will not be
* called.
* @see IForgeItem#damageItem(ItemStack, int, RandomSource, ServerPlayer, Runnable)
*/
default int damageItem(int damage, RandomSource random, @Nullable ServerPlayer player, Runnable onBroken) {
return self().getItem().damageItem(self(), damage, random, player, onBroken);
}
/**
* Called when an item entity for this stack is destroyed. Note: The {@link ItemStack} can be retrieved from the item entity.
*