From be34dd89a9f57a50b7a18926abc125c0ffd7376f Mon Sep 17 00:00:00 2001 From: Mike Garay <61263845+Thelnfamous1@users.noreply.github.com> Date: Fri, 16 Jul 2021 22:12:33 -0500 Subject: [PATCH] Patch several mob classes to let them use modded versions of their ranged weapons (#7845) --- .../minecraft/entity/ICrossbowUser.java.patch | 14 +++ .../ai/brain/task/ShootTargetTask.java.patch | 38 +++++++ .../ai/goal/RangedBowAttackGoal.java.patch | 9 ++ .../goal/RangedCrossbowAttackGoal.java.patch | 29 ++++++ .../monster/AbstractSkeletonEntity.java.patch | 16 ++- .../monster/IllusionerEntity.java.patch | 7 +- .../entity/monster/PillagerEntity.java.patch | 11 +++ .../monster/piglin/PiglinEntity.java.patch | 9 ++ .../monster/piglin/PiglinTasks.java.patch | 9 ++ .../projectile/ProjectileHelper.java.patch | 15 +++ .../item/RangedMobsUseModdedWeaponsTest.java | 99 +++++++++++++++++++ src/test/resources/META-INF/mods.toml | 2 + 12 files changed, 254 insertions(+), 4 deletions(-) create mode 100644 patches/minecraft/net/minecraft/entity/ICrossbowUser.java.patch create mode 100644 patches/minecraft/net/minecraft/entity/ai/brain/task/ShootTargetTask.java.patch create mode 100644 patches/minecraft/net/minecraft/entity/ai/goal/RangedCrossbowAttackGoal.java.patch create mode 100644 patches/minecraft/net/minecraft/entity/monster/PillagerEntity.java.patch create mode 100644 src/test/java/net/minecraftforge/debug/item/RangedMobsUseModdedWeaponsTest.java diff --git a/patches/minecraft/net/minecraft/entity/ICrossbowUser.java.patch b/patches/minecraft/net/minecraft/entity/ICrossbowUser.java.patch new file mode 100644 index 0000000000..5c75034132 --- /dev/null +++ b/patches/minecraft/net/minecraft/entity/ICrossbowUser.java.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/entity/ICrossbowUser.java ++++ b/net/minecraft/entity/ICrossbowUser.java +@@ -24,9 +_,9 @@ + void func_230283_U__(); + + default void func_234281_b_(LivingEntity p_234281_1_, float p_234281_2_) { +- Hand hand = ProjectileHelper.func_221274_a(p_234281_1_, Items.field_222114_py); ++ Hand hand = ProjectileHelper.getWeaponHoldingHand(p_234281_1_, item -> item instanceof CrossbowItem); + ItemStack itemstack = p_234281_1_.func_184586_b(hand); +- if (p_234281_1_.func_233631_a_(Items.field_222114_py)) { ++ if (p_234281_1_.func_233634_a_(item -> item instanceof CrossbowItem)) { + CrossbowItem.func_220014_a(p_234281_1_.field_70170_p, p_234281_1_, hand, itemstack, p_234281_2_, (float)(14 - p_234281_1_.field_70170_p.func_175659_aa().func_151525_a() * 4)); + } + diff --git a/patches/minecraft/net/minecraft/entity/ai/brain/task/ShootTargetTask.java.patch b/patches/minecraft/net/minecraft/entity/ai/brain/task/ShootTargetTask.java.patch new file mode 100644 index 0000000000..a46ebf6d71 --- /dev/null +++ b/patches/minecraft/net/minecraft/entity/ai/brain/task/ShootTargetTask.java.patch @@ -0,0 +1,38 @@ +--- a/net/minecraft/entity/ai/brain/task/ShootTargetTask.java ++++ b/net/minecraft/entity/ai/brain/task/ShootTargetTask.java +@@ -24,7 +_,7 @@ + + protected boolean func_212832_a_(ServerWorld p_212832_1_, E p_212832_2_) { + LivingEntity livingentity = func_233887_a_(p_212832_2_); +- return p_212832_2_.func_233631_a_(Items.field_222114_py) && BrainUtil.func_233876_c_(p_212832_2_, livingentity) && BrainUtil.func_233869_a_(p_212832_2_, livingentity, 0); ++ return p_212832_2_.func_233634_a_(item -> item instanceof CrossbowItem) && BrainUtil.func_233876_c_(p_212832_2_, livingentity) && BrainUtil.func_233869_a_(p_212832_2_, livingentity, 0); + } + + protected boolean func_212834_g_(ServerWorld p_212834_1_, E p_212834_2_, long p_212834_3_) { +@@ -42,7 +_,7 @@ + p_212835_2_.func_184602_cy(); + } + +- if (p_212835_2_.func_233631_a_(Items.field_222114_py)) { ++ if (p_212835_2_.func_233634_a_(item -> item instanceof CrossbowItem)) { + p_212835_2_.func_213671_a(false); + CrossbowItem.func_220011_a(p_212835_2_.func_184607_cu(), false); + } +@@ -51,7 +_,7 @@ + + private void func_233888_a_(E p_233888_1_, LivingEntity p_233888_2_) { + if (this.field_233886_c_ == ShootTargetTask.Status.UNCHARGED) { +- p_233888_1_.func_184598_c(ProjectileHelper.func_221274_a(p_233888_1_, Items.field_222114_py)); ++ p_233888_1_.func_184598_c(ProjectileHelper.getWeaponHoldingHand(p_233888_1_, item -> item instanceof CrossbowItem)); + this.field_233886_c_ = ShootTargetTask.Status.CHARGING; + p_233888_1_.func_213671_a(true); + } else if (this.field_233886_c_ == ShootTargetTask.Status.CHARGING) { +@@ -74,7 +_,7 @@ + } + } else if (this.field_233886_c_ == ShootTargetTask.Status.READY_TO_ATTACK) { + p_233888_1_.func_82196_d(p_233888_2_, 1.0F); +- ItemStack itemstack1 = p_233888_1_.func_184586_b(ProjectileHelper.func_221274_a(p_233888_1_, Items.field_222114_py)); ++ ItemStack itemstack1 = p_233888_1_.func_184586_b(ProjectileHelper.getWeaponHoldingHand(p_233888_1_, item -> item instanceof CrossbowItem)); + CrossbowItem.func_220011_a(itemstack1, false); + this.field_233886_c_ = ShootTargetTask.Status.UNCHARGED; + } diff --git a/patches/minecraft/net/minecraft/entity/ai/goal/RangedBowAttackGoal.java.patch b/patches/minecraft/net/minecraft/entity/ai/goal/RangedBowAttackGoal.java.patch index 1348182a7d..0b60b1a185 100644 --- a/patches/minecraft/net/minecraft/entity/ai/goal/RangedBowAttackGoal.java.patch +++ b/patches/minecraft/net/minecraft/entity/ai/goal/RangedBowAttackGoal.java.patch @@ -9,3 +9,12 @@ } public boolean func_75253_b() { +@@ -117,7 +_,7 @@ + } + } + } else if (--this.field_188503_e <= 0 && this.field_188504_f >= -60) { +- this.field_188499_a.func_184598_c(ProjectileHelper.func_221274_a(this.field_188499_a, Items.field_151031_f)); ++ this.field_188499_a.func_184598_c(ProjectileHelper.getWeaponHoldingHand(this.field_188499_a, item -> item instanceof BowItem)); + } + + } diff --git a/patches/minecraft/net/minecraft/entity/ai/goal/RangedCrossbowAttackGoal.java.patch b/patches/minecraft/net/minecraft/entity/ai/goal/RangedCrossbowAttackGoal.java.patch new file mode 100644 index 0000000000..e4ab4aa729 --- /dev/null +++ b/patches/minecraft/net/minecraft/entity/ai/goal/RangedCrossbowAttackGoal.java.patch @@ -0,0 +1,29 @@ +--- a/net/minecraft/entity/ai/goal/RangedCrossbowAttackGoal.java ++++ b/net/minecraft/entity/ai/goal/RangedCrossbowAttackGoal.java +@@ -33,7 +_,7 @@ + } + + private boolean func_220745_g() { +- return this.field_220748_a.func_233631_a_(Items.field_222114_py); ++ return this.field_220748_a.func_233634_a_(item -> item instanceof CrossbowItem); + } + + public boolean func_75253_b() { +@@ -88,7 +_,7 @@ + this.field_220748_a.func_70671_ap().func_75651_a(livingentity, 30.0F, 30.0F); + if (this.field_220749_b == RangedCrossbowAttackGoal.CrossbowState.UNCHARGED) { + if (!flag2) { +- this.field_220748_a.func_184598_c(ProjectileHelper.func_221274_a(this.field_220748_a, Items.field_222114_py)); ++ this.field_220748_a.func_184598_c(ProjectileHelper.getWeaponHoldingHand(this.field_220748_a, item -> item instanceof CrossbowItem)); + this.field_220749_b = RangedCrossbowAttackGoal.CrossbowState.CHARGING; + this.field_220748_a.func_213671_a(true); + } +@@ -112,7 +_,7 @@ + } + } else if (this.field_220749_b == RangedCrossbowAttackGoal.CrossbowState.READY_TO_ATTACK && flag) { + this.field_220748_a.func_82196_d(livingentity, 1.0F); +- ItemStack itemstack1 = this.field_220748_a.func_184586_b(ProjectileHelper.func_221274_a(this.field_220748_a, Items.field_222114_py)); ++ ItemStack itemstack1 = this.field_220748_a.func_184586_b(ProjectileHelper.getWeaponHoldingHand(this.field_220748_a, item -> item instanceof CrossbowItem)); + CrossbowItem.func_220011_a(itemstack1, false); + this.field_220749_b = RangedCrossbowAttackGoal.CrossbowState.UNCHARGED; + } diff --git a/patches/minecraft/net/minecraft/entity/monster/AbstractSkeletonEntity.java.patch b/patches/minecraft/net/minecraft/entity/monster/AbstractSkeletonEntity.java.patch index 19c22c0949..7ddec472b4 100644 --- a/patches/minecraft/net/minecraft/entity/monster/AbstractSkeletonEntity.java.patch +++ b/patches/minecraft/net/minecraft/entity/monster/AbstractSkeletonEntity.java.patch @@ -1,8 +1,20 @@ --- a/net/minecraft/entity/monster/AbstractSkeletonEntity.java +++ b/net/minecraft/entity/monster/AbstractSkeletonEntity.java -@@ -173,6 +_,8 @@ +@@ -154,7 +_,7 @@ + if (this.field_70170_p != null && !this.field_70170_p.field_72995_K) { + this.field_70714_bg.func_85156_a(this.field_85038_e); + this.field_70714_bg.func_85156_a(this.field_85037_d); +- ItemStack itemstack = this.func_184586_b(ProjectileHelper.func_221274_a(this, Items.field_151031_f)); ++ ItemStack itemstack = this.func_184586_b(ProjectileHelper.getWeaponHoldingHand(this, item -> item instanceof net.minecraft.item.BowItem)); + if (itemstack.func_77973_b() == Items.field_151031_f) { + int i = 20; + if (this.field_70170_p.func_175659_aa() != Difficulty.HARD) { +@@ -171,8 +_,10 @@ + } + public void func_82196_d(LivingEntity p_82196_1_, float p_82196_2_) { - ItemStack itemstack = this.func_213356_f(this.func_184586_b(ProjectileHelper.func_221274_a(this, Items.field_151031_f))); +- ItemStack itemstack = this.func_213356_f(this.func_184586_b(ProjectileHelper.func_221274_a(this, Items.field_151031_f))); ++ ItemStack itemstack = this.func_213356_f(this.func_184586_b(ProjectileHelper.getWeaponHoldingHand(this, item -> item instanceof net.minecraft.item.BowItem))); AbstractArrowEntity abstractarrowentity = this.func_213624_b(itemstack, p_82196_2_); + if (this.func_184614_ca().func_77973_b() instanceof net.minecraft.item.BowItem) + abstractarrowentity = ((net.minecraft.item.BowItem)this.func_184614_ca().func_77973_b()).customArrow(abstractarrowentity); diff --git a/patches/minecraft/net/minecraft/entity/monster/IllusionerEntity.java.patch b/patches/minecraft/net/minecraft/entity/monster/IllusionerEntity.java.patch index 14239b7595..59fce1d051 100644 --- a/patches/minecraft/net/minecraft/entity/monster/IllusionerEntity.java.patch +++ b/patches/minecraft/net/minecraft/entity/monster/IllusionerEntity.java.patch @@ -1,8 +1,11 @@ --- a/net/minecraft/entity/monster/IllusionerEntity.java +++ b/net/minecraft/entity/monster/IllusionerEntity.java -@@ -182,6 +_,8 @@ +@@ -180,8 +_,10 @@ + } + public void func_82196_d(LivingEntity p_82196_1_, float p_82196_2_) { - ItemStack itemstack = this.func_213356_f(this.func_184586_b(ProjectileHelper.func_221274_a(this, Items.field_151031_f))); +- ItemStack itemstack = this.func_213356_f(this.func_184586_b(ProjectileHelper.func_221274_a(this, Items.field_151031_f))); ++ ItemStack itemstack = this.func_213356_f(this.func_184586_b(ProjectileHelper.getWeaponHoldingHand(this, item -> item instanceof net.minecraft.item.BowItem))); AbstractArrowEntity abstractarrowentity = ProjectileHelper.func_221272_a(this, itemstack, p_82196_2_); + if (this.func_184614_ca().func_77973_b() instanceof net.minecraft.item.BowItem) + abstractarrowentity = ((net.minecraft.item.BowItem)this.func_184614_ca().func_77973_b()).customArrow(abstractarrowentity); diff --git a/patches/minecraft/net/minecraft/entity/monster/PillagerEntity.java.patch b/patches/minecraft/net/minecraft/entity/monster/PillagerEntity.java.patch new file mode 100644 index 0000000000..5368b225bf --- /dev/null +++ b/patches/minecraft/net/minecraft/entity/monster/PillagerEntity.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/entity/monster/PillagerEntity.java ++++ b/net/minecraft/entity/monster/PillagerEntity.java +@@ -120,7 +_,7 @@ + public AbstractIllagerEntity.ArmPose func_193077_p() { + if (this.func_213675_dX()) { + return AbstractIllagerEntity.ArmPose.CROSSBOW_CHARGE; +- } else if (this.func_233631_a_(Items.field_222114_py)) { ++ } else if (this.func_233634_a_(item -> item instanceof net.minecraft.item.CrossbowItem)) { + return AbstractIllagerEntity.ArmPose.CROSSBOW_HOLD; + } else { + return this.func_213398_dR() ? AbstractIllagerEntity.ArmPose.ATTACKING : AbstractIllagerEntity.ArmPose.NEUTRAL; diff --git a/patches/minecraft/net/minecraft/entity/monster/piglin/PiglinEntity.java.patch b/patches/minecraft/net/minecraft/entity/monster/piglin/PiglinEntity.java.patch index 122188c492..2e2630647f 100644 --- a/patches/minecraft/net/minecraft/entity/monster/piglin/PiglinEntity.java.patch +++ b/patches/minecraft/net/minecraft/entity/monster/piglin/PiglinEntity.java.patch @@ -1,5 +1,14 @@ --- a/net/minecraft/entity/monster/piglin/PiglinEntity.java +++ b/net/minecraft/entity/monster/piglin/PiglinEntity.java +@@ -265,7 +_,7 @@ + } else if (this.func_234433_eX_()) { + return PiglinAction.CROSSBOW_CHARGE; + } else { +- return this.func_213398_dR() && this.func_233631_a_(Items.field_222114_py) ? PiglinAction.CROSSBOW_HOLD : PiglinAction.DEFAULT; ++ return this.func_213398_dR() && this.func_233634_a_(item -> item instanceof net.minecraft.item.CrossbowItem) ? PiglinAction.CROSSBOW_HOLD : PiglinAction.DEFAULT; + } + } + @@ -307,7 +_,7 @@ } diff --git a/patches/minecraft/net/minecraft/entity/monster/piglin/PiglinTasks.java.patch b/patches/minecraft/net/minecraft/entity/monster/piglin/PiglinTasks.java.patch index 0ff42c6c12..27afcaeb04 100644 --- a/patches/minecraft/net/minecraft/entity/monster/piglin/PiglinTasks.java.patch +++ b/patches/minecraft/net/minecraft/entity/monster/piglin/PiglinTasks.java.patch @@ -36,3 +36,12 @@ return true; } } +@@ -673,7 +_,7 @@ + } + + private static boolean func_234494_c_(LivingEntity p_234494_0_) { +- return p_234494_0_.func_233631_a_(Items.field_222114_py); ++ return p_234494_0_.func_233634_a_(item -> item instanceof net.minecraft.item.CrossbowItem); + } + + private static void func_234501_d_(LivingEntity p_234501_0_) { diff --git a/patches/minecraft/net/minecraft/entity/projectile/ProjectileHelper.java.patch b/patches/minecraft/net/minecraft/entity/projectile/ProjectileHelper.java.patch index 11d717acc7..2305e72540 100644 --- a/patches/minecraft/net/minecraft/entity/projectile/ProjectileHelper.java.patch +++ b/patches/minecraft/net/minecraft/entity/projectile/ProjectileHelper.java.patch @@ -9,3 +9,18 @@ if (d0 == 0.0D) { entity = entity1; vector3d = vector3d1; +@@ -123,8 +_,14 @@ + } + } + ++ @Deprecated // Forge: Use the version below that takes in a Predicate instead of an Item + public static Hand func_221274_a(LivingEntity p_221274_0_, Item p_221274_1_) { + return p_221274_0_.func_184614_ca().func_77973_b() == p_221274_1_ ? Hand.MAIN_HAND : Hand.OFF_HAND; ++ } ++ ++ public static Hand getWeaponHoldingHand(LivingEntity livingEntity, Predicate itemPredicate) ++ { ++ return itemPredicate.test(livingEntity.func_184614_ca().func_77973_b()) ? Hand.MAIN_HAND : Hand.OFF_HAND; + } + + public static AbstractArrowEntity func_221272_a(LivingEntity p_221272_0_, ItemStack p_221272_1_, float p_221272_2_) { diff --git a/src/test/java/net/minecraftforge/debug/item/RangedMobsUseModdedWeaponsTest.java b/src/test/java/net/minecraftforge/debug/item/RangedMobsUseModdedWeaponsTest.java new file mode 100644 index 0000000000..db886b4e6a --- /dev/null +++ b/src/test/java/net/minecraftforge/debug/item/RangedMobsUseModdedWeaponsTest.java @@ -0,0 +1,99 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2021. + * + * This library 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 version 2.1 + * of the License. + * + * This library 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.debug.item; + +import net.minecraft.item.*; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.RegistryObject; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; + +@Mod(RangedMobsUseModdedWeaponsTest.MOD_ID) +public class RangedMobsUseModdedWeaponsTest { + + //Testing if the new alternative for ProjectileHelper.getWeaponHoldingHand works for vanilla mobs + // as well as replacing their usages of LivingEntity#isHolding(Item) with LivingEntity#isHolding(Predicate ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MOD_ID); + + private static final RegistryObject MODDED_BOW = ITEMS.register("modded_bow", () -> + new BowItem(new Item.Properties().tab(ItemGroup.TAB_COMBAT).defaultDurability(384)) + ); + private static final RegistryObject MODDED_CROSSBOW = ITEMS.register("modded_crossbow", () -> + new CrossbowItem(new Item.Properties().tab(ItemGroup.TAB_COMBAT).defaultDurability(326)) + ); + + public RangedMobsUseModdedWeaponsTest() + { + if(ENABLE){ + IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); + ITEMS.register(modEventBus); + modEventBus.addListener(this::onClientSetup); + } + } + + private void onClientSetup(FMLClientSetupEvent event) + { + RangedWeaponModeLProperties.initBowModelProperties(); + RangedWeaponModeLProperties.initCrossbowModelProperties(); + } + + private static class RangedWeaponModeLProperties + { + static void initBowModelProperties() + { + ItemModelsProperties.register(MODDED_BOW.get(), new ResourceLocation("pull"), (itemStack, clientWorld, livingEntity) -> { + if (livingEntity == null) + { + return 0.0F; + } else { + return livingEntity.getUseItem() != itemStack ? 0.0F : (float)(itemStack.getUseDuration() - livingEntity.getUseItemRemainingTicks()) / 20.0F; + } + }); + ItemModelsProperties.register(MODDED_BOW.get(), new ResourceLocation("pulling"), (itemStack, clientWorld, livingEntity) -> livingEntity != null && livingEntity.isUsingItem() && livingEntity.getUseItem() == itemStack ? 1.0F : 0.0F); + } + + static void initCrossbowModelProperties() + { + ItemModelsProperties.register(MODDED_CROSSBOW.get(), new ResourceLocation("pull"), (itemStack, clientWorld, livingEntity) -> { + if (livingEntity == null) + { + return 0.0F; + } else { + return CrossbowItem.isCharged(itemStack) ? 0.0F : (float)(itemStack.getUseDuration() - livingEntity.getUseItemRemainingTicks()) / (float)CrossbowItem.getChargeDuration(itemStack); + } + }); + ItemModelsProperties.register(MODDED_CROSSBOW.get(), new ResourceLocation("pulling"), (itemStack, clientWorld, livingEntity) -> livingEntity != null && livingEntity.isUsingItem() && livingEntity.getUseItem() == itemStack && !CrossbowItem.isCharged(itemStack) ? 1.0F : 0.0F); + ItemModelsProperties.register(MODDED_CROSSBOW.get(), new ResourceLocation("charged"), (itemStack, clientWorld, livingEntity) -> livingEntity != null && CrossbowItem.isCharged(itemStack) ? 1.0F : 0.0F); + ItemModelsProperties.register(MODDED_CROSSBOW.get(), new ResourceLocation("firework"), (itemStack, clientWorld, livingEntity) -> livingEntity != null && CrossbowItem.isCharged(itemStack) && CrossbowItem.containsChargedProjectile(itemStack, Items.FIREWORK_ROCKET) ? 1.0F : 0.0F); + } + } +} \ No newline at end of file diff --git a/src/test/resources/META-INF/mods.toml b/src/test/resources/META-INF/mods.toml index d7c960dbb9..72d8e59c1e 100644 --- a/src/test/resources/META-INF/mods.toml +++ b/src/test/resources/META-INF/mods.toml @@ -124,6 +124,8 @@ license="LGPL v2.1" modId="entity_teleport_event_test" [[mods]] modId="text_linear_filtering_test" +[[mods]] + modId="ranged_mobs_use_modded_weapons_test" [[mods]] modId="fishing_bobber_event_test" [[mods]]