From 861c00fdfc264c332c0c75385f5474b86bfb6dd6 Mon Sep 17 00:00:00 2001 From: Lex Manos Date: Sun, 7 Dec 2014 00:27:51 -0800 Subject: [PATCH] Added Explosion Start and Detonate events to control explosion. Closes #1469 --- .../net/minecraft/world/Explosion.java.patch | 10 ++- .../net/minecraft/world/World.java.patch | 68 +++++++++-------- .../minecraft/world/WorldServer.java.patch | 12 ++- .../event/ForgeEventFactory.java | 24 ++++++ .../event/world/ExplosionEvent.java | 76 +++++++++++++++++++ 5 files changed, 157 insertions(+), 33 deletions(-) create mode 100644 src/main/java/net/minecraftforge/event/world/ExplosionEvent.java diff --git a/patches/minecraft/net/minecraft/world/Explosion.java.patch b/patches/minecraft/net/minecraft/world/Explosion.java.patch index 1d9c98946..00ec8bc4e 100644 --- a/patches/minecraft/net/minecraft/world/Explosion.java.patch +++ b/patches/minecraft/net/minecraft/world/Explosion.java.patch @@ -9,7 +9,15 @@ f1 -= (f3 + 0.3F) * f2; } -@@ -211,8 +211,7 @@ +@@ -113,6 +113,7 @@ + int l = MathHelper.func_76128_c(this.field_77282_d - (double)this.field_77280_f - 1.0D); + int j2 = MathHelper.func_76128_c(this.field_77282_d + (double)this.field_77280_f + 1.0D); + List list = this.field_77287_j.func_72839_b(this.field_77283_e, AxisAlignedBB.func_72330_a((double)i, (double)k, (double)l, (double)j, (double)i2, (double)j2)); ++ net.minecraftforge.event.ForgeEventFactory.onExplosionDetonate(this.field_77287_j, this, list, this.field_77280_f); + Vec3 vec3 = Vec3.func_72443_a(this.field_77284_b, this.field_77285_c, this.field_77282_d); + + for (int i1 = 0; i1 < list.size(); ++i1) +@@ -211,8 +212,7 @@ block.func_149690_a(this.field_77287_j, i, j, k, this.field_77287_j.func_72805_g(i, j, k), 1.0F / this.field_77280_f, 0); } diff --git a/patches/minecraft/net/minecraft/world/World.java.patch b/patches/minecraft/net/minecraft/world/World.java.patch index e31a79604..feb800270 100644 --- a/patches/minecraft/net/minecraft/world/World.java.patch +++ b/patches/minecraft/net/minecraft/world/World.java.patch @@ -290,12 +290,12 @@ + f2 = 1.0F - f2; + return (int)(f2 * 11.0F); + } -+ ++ + /** + * The current sun brightness factor for this dimension. + * 0.0f means no light at all, and 1.0f means maximum sunlight. + * Highly recommended for sunlight detection like solar panel. -+ * ++ * + * @return The current brightness factor + * */ + public float getSunBrightnessFactor(float p_72967_1_) @@ -322,7 +322,7 @@ { + return field_73011_w.getSunBrightness(p_72971_1_); + } -+ ++ + @SideOnly(Side.CLIENT) + public float getSunBrightnessBody(float p_72971_1_) + { @@ -359,7 +359,7 @@ { + return field_73011_w.getCurrentMoonPhaseFactor(); + } -+ ++ + public float getCurrentMoonPhaseFactorBody() + { return WorldProvider.field_111203_a[this.field_73011_w.func_76559_b(this.field_72986_A.func_76073_f())]; @@ -558,7 +558,15 @@ } } } -@@ -2378,13 +2564,15 @@ +@@ -2222,6 +2408,7 @@ + Explosion explosion = new Explosion(this, p_72885_1_, p_72885_2_, p_72885_4_, p_72885_6_, p_72885_8_); + explosion.field_77286_a = p_72885_9_; + explosion.field_82755_b = p_72885_10_; ++ if (net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this, explosion)) return explosion; + explosion.func_77278_a(); + explosion.func_77279_a(true); + return explosion; +@@ -2378,13 +2565,15 @@ public void func_147455_a(int p_147455_1_, int p_147455_2_, int p_147455_3_, TileEntity p_147455_4_) { @@ -578,7 +586,7 @@ Iterator iterator = this.field_147484_a.iterator(); while (iterator.hasNext()) -@@ -2403,40 +2591,22 @@ +@@ -2403,40 +2592,22 @@ else { this.field_147482_g.add(p_147455_4_); @@ -629,7 +637,7 @@ } public void func_147457_a(TileEntity p_147457_1_) -@@ -2453,8 +2623,7 @@ +@@ -2453,8 +2624,7 @@ public static boolean func_147466_a(IBlockAccess p_147466_0_, int p_147466_1_, int p_147466_2_, int p_147466_3_) { Block block = p_147466_0_.func_147439_a(p_147466_1_, p_147466_2_, p_147466_3_); @@ -639,7 +647,7 @@ } public boolean func_147445_c(int p_147445_1_, int p_147445_2_, int p_147445_3_, boolean p_147445_4_) -@@ -2466,7 +2635,7 @@ +@@ -2466,7 +2636,7 @@ if (chunk != null && !chunk.func_76621_g()) { Block block = this.func_147439_a(p_147445_1_, p_147445_2_, p_147445_3_); @@ -648,7 +656,7 @@ } else { -@@ -2491,8 +2660,7 @@ +@@ -2491,8 +2661,7 @@ public void func_72891_a(boolean p_72891_1_, boolean p_72891_2_) { @@ -658,7 +666,7 @@ } public void func_72835_b() -@@ -2502,6 +2670,11 @@ +@@ -2502,6 +2671,11 @@ private void func_72947_a() { @@ -670,7 +678,7 @@ if (this.field_72986_A.func_76059_o()) { this.field_73004_o = 1.0F; -@@ -2515,6 +2688,11 @@ +@@ -2515,6 +2689,11 @@ protected void func_72979_l() { @@ -682,7 +690,7 @@ if (!this.field_73011_w.field_76576_e) { if (!this.field_72995_K) -@@ -2599,6 +2777,7 @@ +@@ -2599,6 +2778,7 @@ { this.field_72993_I.clear(); this.field_72984_F.func_76320_a("buildList"); @@ -690,7 +698,7 @@ int i; EntityPlayer entityplayer; int j; -@@ -2693,6 +2872,11 @@ +@@ -2693,6 +2873,11 @@ public boolean func_72834_c(int p_72834_1_, int p_72834_2_, int p_72834_3_, boolean p_72834_4_) { @@ -702,7 +710,7 @@ BiomeGenBase biomegenbase = this.func_72807_a(p_72834_1_, p_72834_3_); float f = biomegenbase.func_150564_a(p_72834_1_, p_72834_2_, p_72834_3_); -@@ -2748,6 +2932,11 @@ +@@ -2748,6 +2933,11 @@ public boolean func_147478_e(int p_147478_1_, int p_147478_2_, int p_147478_3_, boolean p_147478_4_) { @@ -714,7 +722,7 @@ BiomeGenBase biomegenbase = this.func_72807_a(p_147478_1_, p_147478_3_); float f = biomegenbase.func_150564_a(p_147478_1_, p_147478_2_, p_147478_3_); -@@ -2797,10 +2986,11 @@ +@@ -2797,10 +2987,11 @@ else { Block block = this.func_147439_a(p_98179_1_, p_98179_2_, p_98179_3_); @@ -729,7 +737,7 @@ { i1 = 1; } -@@ -2900,7 +3090,7 @@ +@@ -2900,7 +3091,7 @@ int j4 = i2 + Facing.field_71586_b[i4]; int k4 = j2 + Facing.field_71587_c[i4]; int l4 = k2 + Facing.field_71585_d[i4]; @@ -738,7 +746,7 @@ i3 = this.func_72972_b(p_147463_1_, j4, k4, l4); if (i3 == l2 - i5 && i1 < this.field_72994_J.length) -@@ -2998,10 +3188,10 @@ +@@ -2998,10 +3189,10 @@ public List func_94576_a(Entity p_94576_1_, AxisAlignedBB p_94576_2_, IEntitySelector p_94576_3_) { ArrayList arraylist = new ArrayList(); @@ -753,7 +761,7 @@ for (int i1 = i; i1 <= j; ++i1) { -@@ -3024,10 +3214,10 @@ +@@ -3024,10 +3215,10 @@ public List func_82733_a(Class p_82733_1_, AxisAlignedBB p_82733_2_, IEntitySelector p_82733_3_) { @@ -768,7 +776,7 @@ ArrayList arraylist = new ArrayList(); for (int i1 = i; i1 <= j; ++i1) -@@ -3104,11 +3294,14 @@ +@@ -3104,11 +3295,14 @@ public void func_72868_a(List p_72868_1_) { @@ -786,7 +794,7 @@ } } -@@ -3121,7 +3314,7 @@ +@@ -3121,7 +3315,7 @@ { Block block1 = this.func_147439_a(p_147472_2_, p_147472_3_, p_147472_4_); AxisAlignedBB axisalignedbb = p_147472_5_ ? null : p_147472_1_.func_149668_a(this, p_147472_2_, p_147472_3_, p_147472_4_); @@ -795,17 +803,17 @@ } public PathEntity func_72865_a(Entity p_72865_1_, Entity p_72865_2_, float p_72865_3_, boolean p_72865_4_, boolean p_72865_5_, boolean p_72865_6_, boolean p_72865_7_) -@@ -3226,7 +3419,8 @@ +@@ -3226,7 +3420,8 @@ public int func_72878_l(int p_72878_1_, int p_72878_2_, int p_72878_3_, int p_72878_4_) { - return this.func_147439_a(p_72878_1_, p_72878_2_, p_72878_3_).func_149721_r() ? this.func_94577_B(p_72878_1_, p_72878_2_, p_72878_3_) : this.func_147439_a(p_72878_1_, p_72878_2_, p_72878_3_).func_149709_b(this, p_72878_1_, p_72878_2_, p_72878_3_, p_72878_4_); -+ Block block = this.func_147439_a(p_72878_1_, p_72878_2_, p_72878_3_); ++ Block block = this.func_147439_a(p_72878_1_, p_72878_2_, p_72878_3_); + return block.shouldCheckWeakPower(this, p_72878_1_, p_72878_2_, p_72878_3_, p_72878_4_) ? this.func_94577_B(p_72878_1_, p_72878_2_, p_72878_3_) : block.func_149709_b(this, p_72878_1_, p_72878_2_, p_72878_3_, p_72878_4_); } public boolean func_72864_z(int p_72864_1_, int p_72864_2_, int p_72864_3_) -@@ -3374,7 +3568,7 @@ +@@ -3374,7 +3569,7 @@ public long func_72905_C() { @@ -814,7 +822,7 @@ } public long func_82737_E() -@@ -3384,22 +3578,22 @@ +@@ -3384,22 +3579,22 @@ public long func_72820_D() { @@ -841,7 +849,7 @@ } @SideOnly(Side.CLIENT) -@@ -3419,12 +3613,20 @@ +@@ -3419,12 +3614,20 @@ if (!this.field_72996_f.contains(p_72897_1_)) { @@ -863,7 +871,7 @@ return true; } -@@ -3514,8 +3716,7 @@ +@@ -3514,8 +3717,7 @@ public boolean func_72958_C(int p_72958_1_, int p_72958_2_, int p_72958_3_) { @@ -873,7 +881,7 @@ } public void func_72823_a(String p_72823_1_, WorldSavedData p_72823_2_) -@@ -3569,12 +3770,12 @@ +@@ -3569,12 +3771,12 @@ public int func_72800_K() { @@ -888,7 +896,7 @@ } public Random func_72843_D(int p_72843_1_, int p_72843_2_, int p_72843_3_) -@@ -3598,7 +3799,7 @@ +@@ -3598,7 +3800,7 @@ @SideOnly(Side.CLIENT) public double func_72919_O() { @@ -897,7 +905,7 @@ } public CrashReportCategory func_72914_a(CrashReport p_72914_1_) -@@ -3663,25 +3864,24 @@ +@@ -3663,25 +3865,24 @@ public void func_147453_f(int p_147453_1_, int p_147453_2_, int p_147453_3_, Block p_147453_4_) { @@ -936,7 +944,7 @@ } } } -@@ -3722,4 +3922,110 @@ +@@ -3722,4 +3923,110 @@ iworldaccess.func_147584_b(); } } diff --git a/patches/minecraft/net/minecraft/world/WorldServer.java.patch b/patches/minecraft/net/minecraft/world/WorldServer.java.patch index 7d03e5cab..da5cf59cf 100644 --- a/patches/minecraft/net/minecraft/world/WorldServer.java.patch +++ b/patches/minecraft/net/minecraft/world/WorldServer.java.patch @@ -204,7 +204,15 @@ } public void func_72923_a(Entity p_72923_1_) -@@ -941,19 +986,23 @@ +@@ -851,6 +896,7 @@ + Explosion explosion = new Explosion(this, p_72885_1_, p_72885_2_, p_72885_4_, p_72885_6_, p_72885_8_); + explosion.field_77286_a = p_72885_9_; + explosion.field_82755_b = p_72885_10_; ++ if (net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this, explosion)) return explosion; + explosion.func_77278_a(); + explosion.func_77279_a(false); + +@@ -941,19 +987,23 @@ this.field_73061_a.func_71203_ab().func_148537_a(new S2BPacketChangeGameState(8, this.field_73017_q), this.field_73011_w.field_76574_g); } @@ -232,7 +240,7 @@ } } -@@ -1002,6 +1051,11 @@ +@@ -1002,6 +1052,11 @@ } } diff --git a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java index aec4cd9a0..f34d10838 100644 --- a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java +++ b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java @@ -2,7 +2,9 @@ package net.minecraftforge.event; import java.io.File; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; + import cpw.mods.fml.common.ObfuscationReflectionHelper; import cpw.mods.fml.common.eventhandler.Event.Result; import net.minecraft.block.Block; @@ -16,6 +18,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; +import net.minecraft.world.Explosion; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraft.world.biome.BiomeGenBase; @@ -38,6 +41,7 @@ import net.minecraftforge.event.entity.player.PlayerUseItemEvent; import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.BlockEvent.MultiPlaceEvent; import net.minecraftforge.event.world.BlockEvent.PlaceEvent; +import net.minecraftforge.event.world.ExplosionEvent; import net.minecraftforge.event.world.WorldEvent; public class ForgeEventFactory @@ -216,4 +220,24 @@ public class ForgeEventFactory File dir = ObfuscationReflectionHelper.getPrivateValue(SaveHandler.class, sh, "playersDirectory", "field_"+"75771_c"); MinecraftForge.EVENT_BUS.post(new PlayerEvent.LoadFromFile(player, dir, uuidString)); } + + public static boolean onExplosionStart(World world, Explosion explosion) + { + return MinecraftForge.EVENT_BUS.post(new ExplosionEvent.Start(world, explosion)); + } + + public static void onExplosionDetonate(World world, Explosion explosion, List list, double diameter) + { + //Filter entities to only those who are effected, to prevent modders from seeing more then will be hurt. + /* Enable this if we get issues with modders looping to much. + Iterator itr = list.iterator(); + while (itr.hasNext()) + { + Entity e = itr.next(); + double dist = e.getDistance(explosion.explosionX, explosion.explosionY, explosion.explosionZ) / diameter; + if (dist > 1.0F) itr.remove(); + } + */ + MinecraftForge.EVENT_BUS.post(new ExplosionEvent.Detonate(world, explosion, list)); + } } diff --git a/src/main/java/net/minecraftforge/event/world/ExplosionEvent.java b/src/main/java/net/minecraftforge/event/world/ExplosionEvent.java new file mode 100644 index 000000000..9ca0e579b --- /dev/null +++ b/src/main/java/net/minecraftforge/event/world/ExplosionEvent.java @@ -0,0 +1,76 @@ +package net.minecraftforge.event.world; + +import java.util.List; + +import cpw.mods.fml.common.eventhandler.Cancelable; +import cpw.mods.fml.common.eventhandler.Event; +import net.minecraft.entity.Entity; +import net.minecraft.world.ChunkPosition; +import net.minecraft.world.Explosion; +import net.minecraft.world.World; + +/** ExplosionEvent triggers when an explosion happens in the world.
+ *
+ * ExplosionEvent.Start is fired before the explosion actually occurs.
+ * ExplosionEvent.Detonate is fired once the explosion has a list of affected blocks and entities.
+ *
+ * ExplosionEvent.Start is {@link Cancelable}.
+ * ExplosionEvent.Detonate can modify the affected blocks and entities.
+ * Children do not use {@link HasResult}.
+ * Children of this event are fired on the {@link MinecraftForge#EVENT_BUS}.
+ */ +public class ExplosionEvent extends Event +{ + public final World world; + public final Explosion explosion; + + public ExplosionEvent(World world, Explosion explosion) + { + this.world = world; + this.explosion = explosion; + } + + /** ExplosionEvent.Start is fired before the explosion actually occurs. Canceling this event will stop the explosion.
+ *
+ * This event is {@link Cancelable}.
+ * This event does not use {@link HasResult}.
+ * This event is fired on the {@link MinecraftForge#EVENT_BUS}.
+ */ + @Cancelable + public static class Start extends ExplosionEvent + { + public Start(World world, Explosion explosion) + { + super(world, explosion); + } + } + + /** ExplosionEvent.Detonate is fired once the explosion has a list of affected blocks and entities. These lists can be modified to change the outcome.
+ *
+ * This event is not {@link Cancelable}.
+ * This event does not use {@link HasResult}.
+ * This event is fired on the {@link MinecraftForge#EVENT_BUS}.
+ */ + public static class Detonate extends ExplosionEvent + { + private final List entityList; + + public Detonate(World world, Explosion explosion, List entityList) + { + super(world, explosion); + this.entityList = entityList; + } + + /** return the list of blocks affected by the explosion. */ + public List getAffectedBlocks() + { + return explosion.affectedBlockPositions; + } + + /** return the list of entities affected by the explosion. */ + public List getAffectedEntities() + { + return entityList; + } + } +} \ No newline at end of file