Add ModifyItemAttributeModifiersCallback ()

* Add ItemAttributeModifiersCallback

* fix checkstyle errors

* fix checkstyle errors v2

* Edit javadoc per Technician's review

* Update fabric-item-api-v1/src/main/java/net/fabricmc/fabric/api/item/v1/ItemAttributeModifiersCallback.java

Co-authored-by: Juuxel <6596629+Juuxel@users.noreply.github.com>

* Change functional interface name per Juuz's review

* Change name to ModifyItemAttributeModifiers per Juuz and Technician's request

* Forgot to add callback to the name

* Return mutable map

* Remove unused import

Co-authored-by: Juuxel <6596629+Juuxel@users.noreply.github.com>
This commit is contained in:
frqnny 2022-05-20 13:17:48 -04:00 committed by GitHub
parent a6b0947818
commit 85719ab7b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 106 additions and 2 deletions
fabric-item-api-v1/src
main/java/net/fabricmc/fabric
testmod
java/net/fabricmc/fabric/test/item
resources

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.api.item.v1;
import com.google.common.collect.Multimap;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.item.ItemStack;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
/**
* Stack-aware attribute modifier callback for foreign items.
* Instead of using Mixin to change attribute modifiers in items not in your mod,
* you can use this event instead, either checking the Item itself or using a tag.
* This event provides you with a guaranteed mutable map you can put attribute modifiers in.
* Do not use for your own Item classes; see {@link FabricItem#getAttributeModifiers} instead.
* For example, the following code modifies a Diamond Helmet to give you five extra hearts when wearing.
*
* <pre>
* {@code
* ModifyItemAttributeModifiersCallback.EVENT.register((stack, slot, attributeModifiers) -> {
* if (stack.isOf(Items.DIAMOND_HELMET) && slot.getEntitySlotId() == HEAD_SLOT_ID) {
* attributeModifiers.put(EntityAttributes.GENERIC_MAX_HEALTH, MODIFIER);
* }
* });
* }
* </pre>
*/
@FunctionalInterface
public interface ModifyItemAttributeModifiersCallback {
void modifyAttributeModifiers(ItemStack stack, EquipmentSlot slot, Multimap<EntityAttribute, EntityAttributeModifier> attributeModifiers);
Event<ModifyItemAttributeModifiersCallback> EVENT = EventFactory.createArrayBacked(
ModifyItemAttributeModifiersCallback.class,
callbacks -> (stack, slot, attributeModifiers) -> {
for (ModifyItemAttributeModifiersCallback callback : callbacks) {
callback.modifyAttributeModifiers(stack, slot, attributeModifiers);
}
}
);
}

View file

@ -18,6 +18,7 @@ package net.fabricmc.fabric.mixin.item;
import java.util.function.Consumer;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@ -37,6 +38,7 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.fabricmc.fabric.api.item.v1.CustomDamageHandler;
import net.fabricmc.fabric.api.item.v1.ModifyItemAttributeModifiersCallback;
import net.fabricmc.fabric.impl.item.ItemExtensions;
@Mixin(ItemStack.class)
@ -80,7 +82,11 @@ public abstract class ItemStackMixin {
)
)
public Multimap<EntityAttribute, EntityAttributeModifier> hookGetAttributeModifiers(Item item, EquipmentSlot slot) {
return item.getAttributeModifiers((ItemStack) (Object) this, slot);
ItemStack stack = (ItemStack) (Object) this;
//we need to ensure it is modifiable for the callback
Multimap<EntityAttribute, EntityAttributeModifier> attributeModifiers = HashMultimap.create(item.getAttributeModifiers(stack, slot));
ModifyItemAttributeModifiersCallback.EVENT.invoker().modifyAttributeModifiers(stack, slot, attributeModifiers);
return attributeModifiers;
}
@Redirect(

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.test.item;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.item.Items;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.item.v1.ModifyItemAttributeModifiersCallback;
public class ModifyItemAttributeModifiersCallbackTest implements ModInitializer {
public static final int HEAD_SLOT_ID = 3;
public static final EntityAttributeModifier MODIFIER = new EntityAttributeModifier("generic_max_health_modifier", 5.0, EntityAttributeModifier.Operation.ADDITION);
@Override
public void onInitialize() {
ModifyItemAttributeModifiersCallback.EVENT.register((stack, slot, attributeModifiers) -> {
if (stack.isOf(Items.DIAMOND_HELMET) && slot.getEntitySlotId() == HEAD_SLOT_ID) {
attributeModifiers.put(EntityAttributes.GENERIC_MAX_HEALTH, MODIFIER);
}
});
}
}

View file

@ -12,7 +12,8 @@
"main": [
"net.fabricmc.fabric.test.item.CustomDamageTest",
"net.fabricmc.fabric.test.item.FabricItemSettingsTests",
"net.fabricmc.fabric.test.item.ItemUpdateAnimationTest"
"net.fabricmc.fabric.test.item.ItemUpdateAnimationTest",
"net.fabricmc.fabric.test.item.ModifyItemAttributeModifiersCallbackTest"
],
"client": [
"net.fabricmc.fabric.test.item.client.TooltipTests"