Bläddra i källkod

Add getCustomEquipmentSlot

shedaniel 4 år sedan
förälder
incheckning
35145b9acb

+ 16 - 2
common/src/main/java/me/shedaniel/architectury/extensions/ItemExtension.java

@@ -19,15 +19,29 @@
 
 package me.shedaniel.architectury.extensions;
 
+import net.minecraft.world.entity.EquipmentSlot;
 import net.minecraft.world.entity.player.Player;
 import net.minecraft.world.item.ItemStack;
+import org.jetbrains.annotations.Nullable;
 
 public interface ItemExtension {
     /**
      * Invoked every tick when this item is equipped.
      *
-     * @param stack  the item stack of the armor
+     * @param stack  the item stack
      * @param player the player wearing the armor
      */
-    void tickArmor(ItemStack stack, Player player);
+    default void tickArmor(ItemStack stack, Player player) {
+    }
+    
+    /**
+     * Returns the {@link EquipmentSlot} for {@link ItemStack}.
+     *
+     * @param stack the item stack
+     * @return the {@link EquipmentSlot}, return {@code null} to default to vanilla's {@link net.minecraft.world.entity.Mob#getEquipmentSlotForItem(ItemStack)}
+     */
+    @Nullable
+    default EquipmentSlot getCustomEquipmentSlot(ItemStack stack) {
+        return null;
+    }
 }

+ 44 - 0
fabric/src/main/java/me/shedaniel/architectury/mixin/fabric/MixinMob.java

@@ -0,0 +1,44 @@
+/*
+ * This file is part of architectury.
+ * Copyright (C) 2020, 2021 shedaniel
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package me.shedaniel.architectury.mixin.fabric;
+
+import me.shedaniel.architectury.extensions.ItemExtension;
+import net.minecraft.world.entity.EquipmentSlot;
+import net.minecraft.world.entity.Mob;
+import net.minecraft.world.item.Item;
+import net.minecraft.world.item.ItemStack;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+
+@Mixin(Mob.class)
+public class MixinMob {
+    @Inject(method = "getEquipmentSlotForItem", at = @At("HEAD"), cancellable = true)
+    private static void getEquipmentSlotForItem(ItemStack stack, CallbackInfoReturnable<EquipmentSlot> cir) {
+        Item item = stack.getItem();
+        if (item instanceof ItemExtension) {
+            EquipmentSlot slot = ((ItemExtension) item).getCustomEquipmentSlot(stack);
+            if (slot != null) {
+                cir.setReturnValue(slot);
+            }
+        }
+    }
+}

+ 29 - 29
fabric/src/main/resources/architectury.mixins.json

@@ -1,31 +1,31 @@
 {
-  "required": true,
-  "package": "me.shedaniel.architectury.mixin.fabric",
-  "plugin": "me.shedaniel.architectury.plugin.fabric.ArchitecturyMixinPlugin",
-  "compatibilityLevel": "JAVA_8",
-  "minVersion": "0.7.11",
-  "client": [
-    "client.MixinClientLevel",
-    "client.MixinClientPacketListener",
-    "client.MixinDebugScreenOverlay",
-    "client.MixinEffectInstance",
-    "client.MixinGameRenderer",
-    "client.MixinIntegratedServer",
-    "client.MixinKeyboardHandler",
-    "client.MixinMinecraft",
-    "client.MixinMouseHandler",
-    "client.MixinMultiPlayerGameMode",
-    "client.MixinScreen",
-    "client.MixinTextureAtlas"
-  ],
-  "mixins": [
-    "ExplosionPreInvoker", "LivingDeathInvoker", "MixinBlockEntityExtension", "MixinBlockItem", "MixinCollisionContext", "MixinCommands",
-    "MixinDedicatedServer", "MixinEntityCollisionContext", "MixinExplosion", "MixinFurnaceResultSlot", "MixinInventory", "MixinItemEntity", "MixinLivingEntity",
-    "MixinPlayer", "MixinPlayerAdvancements", "MixinPlayerList", "MixinResultSlot", "MixinServerGamePacketListenerImpl", "MixinServerLevel",
-    "MixinServerPlayer", "MixinServerPlayerGameMode", "PlayerAttackInvoker"
-  ],
-  "injectors": {
-    "maxShiftBy": 5,
-    "defaultRequire": 1
-  }
+    "required": true,
+    "package": "me.shedaniel.architectury.mixin.fabric",
+    "plugin": "me.shedaniel.architectury.plugin.fabric.ArchitecturyMixinPlugin",
+    "compatibilityLevel": "JAVA_8",
+    "minVersion": "0.7.11",
+    "client": [
+        "client.MixinClientLevel",
+        "client.MixinClientPacketListener",
+        "client.MixinDebugScreenOverlay",
+        "client.MixinEffectInstance",
+        "client.MixinGameRenderer",
+        "client.MixinIntegratedServer",
+        "client.MixinKeyboardHandler",
+        "client.MixinMinecraft",
+        "client.MixinMouseHandler",
+        "client.MixinMultiPlayerGameMode",
+        "client.MixinScreen",
+        "client.MixinTextureAtlas"
+    ],
+    "mixins": [
+        "ExplosionPreInvoker", "LivingDeathInvoker", "MixinBlockEntityExtension", "MixinBlockItem", "MixinCollisionContext", "MixinCommands",
+        "MixinDedicatedServer", "MixinEntityCollisionContext", "MixinExplosion", "MixinFurnaceResultSlot", "MixinInventory", "MixinItemEntity",
+        "MixinLivingEntity", "MixinMob", "MixinPlayer", "MixinPlayerAdvancements", "MixinPlayerList", "MixinResultSlot", "MixinServerGamePacketListenerImpl",
+        "MixinServerLevel", "MixinServerPlayer", "MixinServerPlayerGameMode", "PlayerAttackInvoker"
+    ],
+    "injectors": {
+        "maxShiftBy": 5,
+        "defaultRequire": 1
+    }
 }

+ 8 - 0
forge/src/main/java/me/shedaniel/architectury/mixin/forge/MixinItemExtension.java

@@ -20,10 +20,12 @@
 package me.shedaniel.architectury.mixin.forge;
 
 import me.shedaniel.architectury.extensions.ItemExtension;
+import net.minecraft.world.entity.EquipmentSlot;
 import net.minecraft.world.entity.player.Player;
 import net.minecraft.world.item.ItemStack;
 import net.minecraft.world.level.Level;
 import net.minecraftforge.common.extensions.IForgeItem;
+import org.jetbrains.annotations.Nullable;
 import org.spongepowered.asm.mixin.Mixin;
 
 @Mixin(ItemExtension.class)
@@ -32,4 +34,10 @@ public interface MixinItemExtension extends IForgeItem {
     default void onArmorTick(ItemStack stack, Level world, Player player) {
         ((ItemExtension) this).tickArmor(stack, player);
     }
+    
+    @Nullable
+    @Override
+    default EquipmentSlot getEquipmentSlot(ItemStack stack) {
+        return ((ItemExtension) this).getCustomEquipmentSlot(stack);
+    }
 }

+ 3 - 0
testmod-common/src/main/java/me/shedaniel/architectury/test/registry/TestRegistries.java

@@ -24,6 +24,7 @@ import me.shedaniel.architectury.registry.BlockProperties;
 import me.shedaniel.architectury.registry.DeferredRegister;
 import me.shedaniel.architectury.registry.RegistrySupplier;
 import me.shedaniel.architectury.test.TestMod;
+import me.shedaniel.architectury.test.registry.objects.EquippableTickingItem;
 import me.shedaniel.architectury.test.tab.TestCreativeTabs;
 import net.minecraft.core.BlockPos;
 import net.minecraft.core.Registry;
@@ -44,6 +45,8 @@ public class TestRegistries {
     
     public static final RegistrySupplier<Item> TEST_ITEM = ITEMS.register("test_item", () ->
             new Item(new Item.Properties().tab(TestCreativeTabs.TEST_TAB)));
+    public static final RegistrySupplier<Item> TEST_EQUIPPABLE = ITEMS.register("test_eqippable", () ->
+            new EquippableTickingItem(new Item.Properties().tab(TestCreativeTabs.TEST_TAB)));
     
     public static final RegistrySupplier<Block> TEST_BLOCK = BLOCKS.register("test_block", () ->
             new Block(BlockProperties.copy(Blocks.STONE)));

+ 46 - 0
testmod-common/src/main/java/me/shedaniel/architectury/test/registry/objects/EquippableTickingItem.java

@@ -0,0 +1,46 @@
+/*
+ * This file is part of architectury.
+ * Copyright (C) 2020, 2021 shedaniel
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package me.shedaniel.architectury.test.registry.objects;
+
+import me.shedaniel.architectury.extensions.ItemExtension;
+import me.shedaniel.architectury.test.TestMod;
+import net.minecraft.network.chat.TranslatableComponent;
+import net.minecraft.world.entity.EquipmentSlot;
+import net.minecraft.world.entity.player.Player;
+import net.minecraft.world.item.Item;
+import net.minecraft.world.item.ItemStack;
+import org.jetbrains.annotations.Nullable;
+
+public class EquippableTickingItem extends Item implements ItemExtension {
+    public EquippableTickingItem(Properties properties) {
+        super(properties);
+    }
+    
+    @Override
+    public void tickArmor(ItemStack stack, Player player) {
+        TestMod.SINK.accept("Ticking " + new TranslatableComponent(stack.getDescriptionId()).getString());
+    }
+    
+    @Nullable
+    @Override
+    public EquipmentSlot getCustomEquipmentSlot(ItemStack stack) {
+        return EquipmentSlot.HEAD;
+    }
+}