From bbf1bef7d31ccf297af7253b880ba7575f3f17bd Mon Sep 17 00:00:00 2001 From: Melonslise Date: Sun, 17 Dec 2017 05:03:45 +0300 Subject: [PATCH] Added LivingKnockBackEvent event to allow better control over knock back effects. (#4503) --- .../entity/EntityLivingBase.java.patch | 46 +++++---- .../net/minecraftforge/common/ForgeHooks.java | 8 ++ .../entity/living/LivingKnockBackEvent.java | 95 +++++++++++++++++++ .../debug/KnockBackHookTest.java | 30 ++++++ 4 files changed, 161 insertions(+), 18 deletions(-) create mode 100644 src/main/java/net/minecraftforge/event/entity/living/LivingKnockBackEvent.java create mode 100644 src/test/java/net/minecraftforge/debug/KnockBackHookTest.java diff --git a/patches/minecraft/net/minecraft/entity/EntityLivingBase.java.patch b/patches/minecraft/net/minecraft/entity/EntityLivingBase.java.patch index 14d681529c..294442cf19 100644 --- a/patches/minecraft/net/minecraft/entity/EntityLivingBase.java.patch +++ b/patches/minecraft/net/minecraft/entity/EntityLivingBase.java.patch @@ -141,7 +141,17 @@ } this.field_70170_p.func_72960_a(this, (byte)3); -@@ -1253,15 +1273,7 @@ +@@ -1195,6 +1215,9 @@ + + public void func_70653_a(Entity p_70653_1_, float p_70653_2_, double p_70653_3_, double p_70653_5_) + { ++ net.minecraftforge.event.entity.living.LivingKnockBackEvent event = net.minecraftforge.common.ForgeHooks.onLivingKnockBack(this, p_70653_1_, p_70653_2_, p_70653_3_, p_70653_5_); ++ if(event.isCanceled()) return; ++ p_70653_2_ = event.getStrength(); p_70653_3_ = event.getRatioX(); p_70653_5_ = event.getRatioZ(); + if (this.field_70146_Z.nextDouble() >= this.func_110148_a(SharedMonsterAttributes.field_111266_c).func_111126_e()) + { + this.field_70160_al = true; +@@ -1253,15 +1276,7 @@ BlockPos blockpos = new BlockPos(i, j, k); IBlockState iblockstate = this.field_70170_p.func_180495_p(blockpos); Block block = iblockstate.func_177230_c(); @@ -158,7 +168,7 @@ } } -@@ -1287,6 +1299,9 @@ +@@ -1287,6 +1302,9 @@ public void func_180430_e(float p_180430_1_, float p_180430_2_) { @@ -168,7 +178,7 @@ super.func_180430_e(p_180430_1_, p_180430_2_); PotionEffect potioneffect = this.func_70660_b(MobEffects.field_76430_j); float f = potioneffect == null ? 0.0F : (float)(potioneffect.func_76458_c() + 1); -@@ -1303,7 +1318,7 @@ +@@ -1303,7 +1321,7 @@ if (iblockstate.func_185904_a() != Material.field_151579_a) { @@ -177,7 +187,7 @@ this.func_184185_a(soundtype.func_185842_g(), soundtype.func_185843_a() * 0.5F, soundtype.func_185847_b() * 0.75F); } } -@@ -1380,17 +1395,20 @@ +@@ -1380,17 +1398,20 @@ { if (!this.func_180431_b(p_70665_1_)) { @@ -199,7 +209,7 @@ this.func_110149_m(this.func_110139_bj() - p_70665_2_); } } -@@ -1447,6 +1465,11 @@ +@@ -1447,6 +1468,11 @@ public void func_184609_a(EnumHand p_184609_1_) { @@ -211,7 +221,7 @@ if (!this.field_82175_bq || this.field_110158_av >= this.func_82166_i() / 2 || this.field_110158_av < 0) { this.field_110158_av = -1; -@@ -1694,7 +1717,7 @@ +@@ -1694,7 +1720,7 @@ if (!this.field_70170_p.func_184143_b(axisalignedbb1)) { @@ -220,7 +230,7 @@ { this.func_70634_a(d11, this.field_70163_u + 1.0D, d12); return; -@@ -1702,14 +1725,14 @@ +@@ -1702,14 +1728,14 @@ BlockPos blockpos = new BlockPos(d11, this.field_70163_u - 1.0D, d12); @@ -237,7 +247,7 @@ { d1 = d11; d13 = this.field_70163_u + 2.0D; -@@ -1781,6 +1804,7 @@ +@@ -1781,6 +1807,7 @@ } this.field_70160_al = true; @@ -245,7 +255,7 @@ } protected void func_70629_bd() -@@ -1874,7 +1898,8 @@ +@@ -1874,7 +1901,8 @@ if (this.field_70122_E) { @@ -255,7 +265,7 @@ } float f7 = 0.16277136F / (f6 * f6 * f6); -@@ -1894,7 +1919,8 @@ +@@ -1894,7 +1922,8 @@ if (this.field_70122_E) { @@ -265,7 +275,7 @@ } if (this.func_70617_f_()) -@@ -2054,6 +2080,7 @@ +@@ -2054,6 +2083,7 @@ public void func_70071_h_() { @@ -273,7 +283,7 @@ super.func_70071_h_(); this.func_184608_ct(); -@@ -2096,7 +2123,9 @@ +@@ -2096,7 +2126,9 @@ if (!ItemStack.func_77989_b(itemstack1, itemstack)) { @@ -283,7 +293,7 @@ if (!itemstack.func_190926_b()) { -@@ -2575,6 +2604,40 @@ +@@ -2575,6 +2607,40 @@ this.field_70752_e = true; } @@ -324,7 +334,7 @@ public abstract EnumHandSide func_184591_cq(); public boolean func_184587_cr() -@@ -2595,12 +2658,19 @@ +@@ -2595,12 +2661,19 @@ if (itemstack == this.field_184627_bm) { @@ -345,7 +355,7 @@ { this.func_71036_o(); } -@@ -2618,8 +2688,10 @@ +@@ -2618,8 +2691,10 @@ if (!itemstack.func_190926_b() && !this.func_184587_cr()) { @@ -357,7 +367,7 @@ if (!this.field_70170_p.field_72995_K) { -@@ -2700,7 +2772,9 @@ +@@ -2700,7 +2775,9 @@ if (!this.field_184627_bm.func_190926_b() && this.func_184587_cr()) { this.func_184584_a(this.field_184627_bm, 16); @@ -368,7 +378,7 @@ this.func_184602_cy(); } } -@@ -2724,7 +2798,8 @@ +@@ -2724,7 +2801,8 @@ { if (!this.field_184627_bm.func_190926_b()) { @@ -378,7 +388,7 @@ } this.func_184602_cy(); -@@ -2852,6 +2927,31 @@ +@@ -2852,6 +2930,31 @@ return true; } diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/src/main/java/net/minecraftforge/common/ForgeHooks.java index 355ba5187f..1396139c98 100644 --- a/src/main/java/net/minecraftforge/common/ForgeHooks.java +++ b/src/main/java/net/minecraftforge/common/ForgeHooks.java @@ -120,6 +120,7 @@ import net.minecraftforge.event.entity.living.LivingEvent.LivingJumpEvent; import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; import net.minecraftforge.event.entity.living.LivingFallEvent; import net.minecraftforge.event.entity.living.LivingHurtEvent; +import net.minecraftforge.event.entity.living.LivingKnockBackEvent; import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent; import net.minecraftforge.event.entity.living.LootingLevelEvent; import net.minecraftforge.event.entity.player.AnvilRepairEvent; @@ -560,6 +561,13 @@ public class ForgeHooks return !MinecraftForge.EVENT_BUS.post(new LivingAttackEvent(entity, src, amount)); } + public static LivingKnockBackEvent onLivingKnockBack(EntityLivingBase target, Entity attacker, float strength, double ratioX, double ratioZ) + { + LivingKnockBackEvent event = new LivingKnockBackEvent(target, attacker, strength, ratioX, ratioZ); + MinecraftForge.EVENT_BUS.post(event); + return event; + } + public static float onLivingHurt(EntityLivingBase entity, DamageSource src, float amount) { LivingHurtEvent event = new LivingHurtEvent(entity, src, amount); diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingKnockBackEvent.java b/src/main/java/net/minecraftforge/event/entity/living/LivingKnockBackEvent.java new file mode 100644 index 0000000000..138c7ab193 --- /dev/null +++ b/src/main/java/net/minecraftforge/event/entity/living/LivingKnockBackEvent.java @@ -0,0 +1,95 @@ +/* + * Minecraft Forge + * Copyright (c) 2017. + * + * 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.event.entity.living; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntityMob; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.DamageSource; +import net.minecraftforge.common.ForgeHooks; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.eventhandler.Cancelable; + +/** + * LivingKnockBackEvent is fired when a living entity is about to be knocked back.
+ * This event is fired whenever an Entity is knocked back in + * {@link EntityLivingBase#attackEntityFrom(DamageSource, float)}, + * {@link EntityLivingBase#blockWithShield(EntityLivingBase)}, + * {@link EntityMob#attackEntityAsMob(Entity)} and + * {@link EntityPlayer#attackTargetEntityWithCurrentItem(Entity)}
+ *
+ * This event is fired via {@link ForgeHooks#onLivingKnockBack(EntityLivingBase, Entity, float, double, double)}.
+ *
+ * {@link #attacker} contains the Entity that caused the knock back.
+ * {@link #strength} contains the strength of the knock back.
+ * {@link #ratioX} contains the x ratio of the knock back.
+ * {@link #ratioZ} contains the z ratio of the knock back.
+ *
+ * This event is {@link Cancelable}.
+ * If this event is canceled, the entity is not knocked back.
+ *
+ * This event does not have a result. {@link HasResult}
+ *
+ * This event is fired on the {@link MinecraftForge#EVENT_BUS}. + **/ +@Cancelable +public class LivingKnockBackEvent extends LivingEvent +{ + protected Entity attacker; + protected float strength; + protected double ratioX, ratioZ; + protected final Entity originalAttacker; + protected final float originalStrength; + protected final double originalRatioX, originalRatioZ; + + public LivingKnockBackEvent(EntityLivingBase target, Entity attacker, float strength, double ratioX, double ratioZ) + { + super(target); + this.attacker = this.originalAttacker = attacker; + this.strength = this.originalStrength = strength; + this.ratioX = this.originalRatioX = ratioX; + this.ratioZ = this.originalRatioZ = ratioZ; + } + + public Entity getAttacker() {return this.attacker;} + + public float getStrength() {return this.strength;} + + public double getRatioX() {return this.ratioX;} + + public double getRatioZ() {return this.ratioZ;} + + public Entity getOriginalAttacker() {return this.originalAttacker;} + + public float getOriginalStrength() {return this.originalStrength;} + + public double getOriginalRatioX() {return this.originalRatioX;} + + public double getOriginalRatioZ() {return this.originalRatioZ;} + + public void setAttacker(Entity attacker) {this.attacker = attacker;} + + public void setStrength(float strength) {this.strength = strength;} + + public void setRatioX(double ratioX) {this.ratioX = ratioX;} + + public void setRatioZ(double ratioZ) {this.ratioZ = ratioZ;} +} \ No newline at end of file diff --git a/src/test/java/net/minecraftforge/debug/KnockBackHookTest.java b/src/test/java/net/minecraftforge/debug/KnockBackHookTest.java new file mode 100644 index 0000000000..a494ec887e --- /dev/null +++ b/src/test/java/net/minecraftforge/debug/KnockBackHookTest.java @@ -0,0 +1,30 @@ +package net.minecraftforge.debug; + +import net.minecraft.entity.passive.EntityCow; +import net.minecraft.entity.passive.EntitySheep; +import net.minecraftforge.event.entity.living.LivingKnockBackEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +@Mod(modid = "kbhtest", name = "Knock Back Hook Test", version = "1.0") +@Mod.EventBusSubscriber +public class KnockBackHookTest +{ + private static final boolean ENABLED = false; + + @SubscribeEvent + public static void onKnockBack(LivingKnockBackEvent event) + { + if(ENABLED) + { + if(event.getEntityLiving() instanceof EntitySheep) + { + event.setStrength(0.2F); + } + else if(event.getEntityLiving() instanceof EntityCow) + { + event.setCanceled(true); + } + } + } +} \ No newline at end of file