diff --git a/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/mixin/item/ArmorItemMixin.java b/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/mixin/item/ArmorItemMixin.java new file mode 100644 index 000000000..7e2ebe7b7 --- /dev/null +++ b/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/mixin/item/ArmorItemMixin.java @@ -0,0 +1,55 @@ +/* + * 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.mixin.item; + +import java.util.UUID; + +import com.google.common.collect.ImmutableMultimap; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import net.minecraft.entity.attribute.EntityAttributeModifier; +import net.minecraft.entity.attribute.EntityAttributes; +import net.minecraft.entity.attribute.EntityAttribute; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.item.ArmorItem; +import net.minecraft.item.ArmorMaterial; +import net.minecraft.item.ArmorMaterials; + +@Mixin(ArmorItem.class) +public class ArmorItemMixin { + @Shadow private static @Final UUID[] MODIFIERS; + @Shadow protected @Final float knockbackResistance; + + /* Vanilla only adds a knockback resistance modifier to ArmorItems made of ArmorMaterials.NETHERITE. This mixin + * adds a knockback resistance modifier to any ArmorItem if knockbackResistance is > 0.0F. + */ + @ModifyVariable(method = "<init>", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/ImmutableMultimap$Builder;build()Lcom/google/common/collect/ImmutableMultimap;")) + private ImmutableMultimap.Builder<EntityAttribute, EntityAttributeModifier> fabric_knockbackResistance(ImmutableMultimap.Builder<EntityAttribute, EntityAttributeModifier> builder, ArmorMaterial material, EquipmentSlot slot) { + // Vanilla handles netherite + if (material != ArmorMaterials.NETHERITE && knockbackResistance > 0.0F) { + builder.put(EntityAttributes.GENERIC_KNOCKBACK_RESISTANCE, new EntityAttributeModifier( + MODIFIERS[slot.getEntitySlotId()], "Armor knockback resistance", + knockbackResistance, EntityAttributeModifier.Operation.ADDITION)); + } + + return builder; + } +} diff --git a/fabric-item-api-v1/src/main/resources/fabric-item-api-v1.mixins.json b/fabric-item-api-v1/src/main/resources/fabric-item-api-v1.mixins.json index 524c59b9a..69d431532 100644 --- a/fabric-item-api-v1/src/main/resources/fabric-item-api-v1.mixins.json +++ b/fabric-item-api-v1/src/main/resources/fabric-item-api-v1.mixins.json @@ -5,7 +5,8 @@ "mixins": [ "ItemStackMixin", "ItemMixin", - "LivingEntityMixin" + "LivingEntityMixin", + "ArmorItemMixin" ], "client": [ "client.ClientPlayerInteractionManagerMixin", diff --git a/fabric-item-api-v1/src/testmod/java/net/fabricmc/fabric/test/item/ArmorKnockbackResistanceTest.java b/fabric-item-api-v1/src/testmod/java/net/fabricmc/fabric/test/item/ArmorKnockbackResistanceTest.java new file mode 100644 index 000000000..cfd3b68c4 --- /dev/null +++ b/fabric-item-api-v1/src/testmod/java/net/fabricmc/fabric/test/item/ArmorKnockbackResistanceTest.java @@ -0,0 +1,80 @@ +/* + * 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.EquipmentSlot; +import net.minecraft.item.ArmorItem; +import net.minecraft.item.ArmorMaterial; +import net.minecraft.item.Item; +import net.minecraft.recipe.Ingredient; +import net.minecraft.sound.SoundEvent; +import net.minecraft.sound.SoundEvents; +import net.minecraft.tag.ItemTags; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; + +import net.fabricmc.api.ModInitializer; + +public class ArmorKnockbackResistanceTest implements ModInitializer { + private static final ArmorMaterial WOOD_ARMOR = new ArmorMaterial() { + @Override + public int getDurability(EquipmentSlot slot) { + return 50; + } + + @Override + public int getProtectionAmount(EquipmentSlot slot) { + return 5; + } + + @Override + public int getEnchantability() { + return 1; + } + + @Override + public SoundEvent getEquipSound() { + return SoundEvents.ITEM_ARMOR_EQUIP_GENERIC; + } + + @Override + public Ingredient getRepairIngredient() { + return Ingredient.fromTag(ItemTags.LOGS); + } + + @Override + public String getName() { + return "wood"; + } + + @Override + public float getToughness() { + return 0.0F; + } + + @Override + public float getKnockbackResistance() { + return 0.5F; + } + }; + + @Override + public void onInitialize() { + Registry.register(Registry.ITEM, new Identifier("fabric-item-api-v1-testmod", + "wooden_boots"), new ArmorItem(WOOD_ARMOR, EquipmentSlot.FEET, new Item.Settings())); + } +} diff --git a/fabric-item-api-v1/src/testmod/resources/assets/fabric-item-api-v1-testmod/models/item/wooden_boots.json b/fabric-item-api-v1/src/testmod/resources/assets/fabric-item-api-v1-testmod/models/item/wooden_boots.json new file mode 100644 index 000000000..3afe800aa --- /dev/null +++ b/fabric-item-api-v1/src/testmod/resources/assets/fabric-item-api-v1-testmod/models/item/wooden_boots.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "minecraft:block/oak_log", + "layer1": "minecraft:item/leather_boots", + "layer2": "minecraft:item/leather_boots_overlay" + } +} diff --git a/fabric-item-api-v1/src/testmod/resources/assets/minecraft/textures/models/armor/wood_layer_1.png b/fabric-item-api-v1/src/testmod/resources/assets/minecraft/textures/models/armor/wood_layer_1.png new file mode 100644 index 000000000..d7c688207 Binary files /dev/null and b/fabric-item-api-v1/src/testmod/resources/assets/minecraft/textures/models/armor/wood_layer_1.png differ diff --git a/fabric-item-api-v1/src/testmod/resources/assets/minecraft/textures/models/armor/wood_layer_2.png b/fabric-item-api-v1/src/testmod/resources/assets/minecraft/textures/models/armor/wood_layer_2.png new file mode 100644 index 000000000..2fbda132c Binary files /dev/null and b/fabric-item-api-v1/src/testmod/resources/assets/minecraft/textures/models/armor/wood_layer_2.png differ diff --git a/fabric-item-api-v1/src/testmod/resources/fabric.mod.json b/fabric-item-api-v1/src/testmod/resources/fabric.mod.json index 2750b292a..93e8e9873 100644 --- a/fabric-item-api-v1/src/testmod/resources/fabric.mod.json +++ b/fabric-item-api-v1/src/testmod/resources/fabric.mod.json @@ -13,7 +13,8 @@ "net.fabricmc.fabric.test.item.CustomDamageTest", "net.fabricmc.fabric.test.item.FabricItemSettingsTests", "net.fabricmc.fabric.test.item.ItemUpdateAnimationTest", - "net.fabricmc.fabric.test.item.ModifyItemAttributeModifiersCallbackTest" + "net.fabricmc.fabric.test.item.ModifyItemAttributeModifiersCallbackTest", + "net.fabricmc.fabric.test.item.ArmorKnockbackResistanceTest" ], "client": [ "net.fabricmc.fabric.test.item.client.TooltipTests"