diff --git a/patches/minecraft/net/minecraft/entity/item/EntityFallingBlock.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityFallingBlock.java.patch index a6322acef4..fb9b733281 100644 --- a/patches/minecraft/net/minecraft/entity/item/EntityFallingBlock.java.patch +++ b/patches/minecraft/net/minecraft/entity/item/EntityFallingBlock.java.patch @@ -8,7 +8,15 @@ if (!flag1 && BlockFalling.func_185759_i(this.field_70170_p.func_180495_p(new BlockPos(this.field_70165_t, this.field_70163_u - 0.009999999776482582D, this.field_70161_v)))) { this.field_70122_E = false; -@@ -189,7 +190,7 @@ +@@ -182,14 +183,14 @@ + + if (!this.field_145808_f) + { +- if (this.field_70170_p.func_190527_a(block, blockpos1, true, EnumFacing.UP, (Entity)null) && (flag1 || !BlockFalling.func_185759_i(this.field_70170_p.func_180495_p(blockpos1.func_177977_b()))) && this.field_70170_p.func_180501_a(blockpos1, this.field_175132_d, 3)) ++ if (this.field_70170_p.func_190527_a(block, blockpos1, true, EnumFacing.UP, this) && (flag1 || !BlockFalling.func_185759_i(this.field_70170_p.func_180495_p(blockpos1.func_177977_b()))) && this.field_70170_p.func_180501_a(blockpos1, this.field_175132_d, 3)) + { + if (block instanceof BlockFalling) + { ((BlockFalling)block).func_176502_a_(this.field_70170_p, blockpos1, this.field_175132_d, iblockstate); } diff --git a/patches/minecraft/net/minecraft/entity/monster/EntityEnderman.java.patch b/patches/minecraft/net/minecraft/entity/monster/EntityEnderman.java.patch index ce0edefef9..503fb87781 100644 --- a/patches/minecraft/net/minecraft/entity/monster/EntityEnderman.java.patch +++ b/patches/minecraft/net/minecraft/entity/monster/EntityEnderman.java.patch @@ -39,6 +39,15 @@ { return false; } +@@ -508,7 +522,7 @@ + IBlockState iblockstate1 = world.func_180495_p(blockpos.func_177977_b()); + IBlockState iblockstate2 = this.field_179475_a.func_175489_ck(); + +- if (iblockstate2 != null && this.func_188518_a(world, blockpos, iblockstate2.func_177230_c(), iblockstate, iblockstate1)) ++ if (iblockstate2 != null && this.func_188518_a(world, blockpos, iblockstate2.func_177230_c(), iblockstate, iblockstate1) && net.minecraftforge.event.ForgeEventFactory.onBlockPlace(field_179475_a, new net.minecraftforge.common.util.BlockSnapshot(world, blockpos, iblockstate2), net.minecraft.util.EnumFacing.UP).isCanceled()) + { + world.func_180501_a(blockpos, iblockstate2, 3); + this.field_179475_a.func_175490_a((IBlockState)null); @@ -551,7 +565,7 @@ { return false; diff --git a/patches/minecraft/net/minecraft/item/ItemBlock.java.patch b/patches/minecraft/net/minecraft/item/ItemBlock.java.patch index b750fd2c27..1689154b4e 100644 --- a/patches/minecraft/net/minecraft/item/ItemBlock.java.patch +++ b/patches/minecraft/net/minecraft/item/ItemBlock.java.patch @@ -1,7 +1,11 @@ --- ../src-base/minecraft/net/minecraft/item/ItemBlock.java +++ ../src-work/minecraft/net/minecraft/item/ItemBlock.java -@@ -49,24 +49,12 @@ - if (!itemstack.func_190926_b() && p_180614_1_.func_175151_a(p_180614_3_, p_180614_5_, itemstack) && p_180614_2_.func_190527_a(this.field_150939_a, p_180614_3_, false, p_180614_5_, (Entity)null)) +@@ -46,27 +46,15 @@ + + ItemStack itemstack = p_180614_1_.func_184586_b(p_180614_4_); + +- if (!itemstack.func_190926_b() && p_180614_1_.func_175151_a(p_180614_3_, p_180614_5_, itemstack) && p_180614_2_.func_190527_a(this.field_150939_a, p_180614_3_, false, p_180614_5_, (Entity)null)) ++ if (!itemstack.func_190926_b() && p_180614_1_.func_175151_a(p_180614_3_, p_180614_5_, itemstack) && p_180614_2_.func_190527_a(this.field_150939_a, p_180614_3_, false, p_180614_5_, p_180614_1_)) { int i = this.func_77647_b(itemstack.func_77960_j()); - IBlockState iblockstate1 = this.field_150939_a.func_180642_a(p_180614_2_, p_180614_3_, p_180614_5_, p_180614_6_, p_180614_7_, p_180614_8_, i, p_180614_1_); @@ -37,6 +41,15 @@ { p_179222_3_ = EnumFacing.UP; } +@@ -136,7 +124,7 @@ + p_179222_2_ = p_179222_2_.func_177972_a(p_179222_3_); + } + +- return p_179222_1_.func_190527_a(this.field_150939_a, p_179222_2_, false, p_179222_3_, (Entity)null); ++ return p_179222_1_.func_190527_a(this.field_150939_a, p_179222_2_, false, p_179222_3_, p_179222_4_); + } + + public String func_77667_c(ItemStack p_77667_1_) @@ -171,6 +159,36 @@ public Block func_179223_d() diff --git a/patches/minecraft/net/minecraft/item/ItemBlockSpecial.java.patch b/patches/minecraft/net/minecraft/item/ItemBlockSpecial.java.patch index 57c528072f..bd00e3abd5 100644 --- a/patches/minecraft/net/minecraft/item/ItemBlockSpecial.java.patch +++ b/patches/minecraft/net/minecraft/item/ItemBlockSpecial.java.patch @@ -1,8 +1,11 @@ --- ../src-base/minecraft/net/minecraft/item/ItemBlockSpecial.java +++ ../src-work/minecraft/net/minecraft/item/ItemBlockSpecial.java -@@ -43,7 +43,7 @@ +@@ -41,9 +41,9 @@ - if (!itemstack.func_190926_b() && p_180614_1_.func_175151_a(p_180614_3_, p_180614_5_, itemstack) && p_180614_2_.func_190527_a(this.field_150935_a, p_180614_3_, false, p_180614_5_, (Entity)null)) + ItemStack itemstack = p_180614_1_.func_184586_b(p_180614_4_); + +- if (!itemstack.func_190926_b() && p_180614_1_.func_175151_a(p_180614_3_, p_180614_5_, itemstack) && p_180614_2_.func_190527_a(this.field_150935_a, p_180614_3_, false, p_180614_5_, (Entity)null)) ++ if (!itemstack.func_190926_b() && p_180614_1_.func_175151_a(p_180614_3_, p_180614_5_, itemstack) && p_180614_2_.func_190527_a(this.field_150935_a, p_180614_3_, false, p_180614_5_, p_180614_1_)) { - IBlockState iblockstate1 = this.field_150935_a.func_180642_a(p_180614_2_, p_180614_3_, p_180614_5_, p_180614_6_, p_180614_7_, p_180614_8_, 0, p_180614_1_); + IBlockState iblockstate1 = this.field_150935_a.getStateForPlacement(p_180614_2_, p_180614_3_, p_180614_5_, p_180614_6_, p_180614_7_, p_180614_8_, 0, p_180614_1_, p_180614_4_); diff --git a/patches/minecraft/net/minecraft/item/ItemRedstone.java.patch b/patches/minecraft/net/minecraft/item/ItemRedstone.java.patch new file mode 100644 index 0000000000..91d88ef8bd --- /dev/null +++ b/patches/minecraft/net/minecraft/item/ItemRedstone.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/item/ItemRedstone.java ++++ ../src-work/minecraft/net/minecraft/item/ItemRedstone.java +@@ -25,7 +25,7 @@ + BlockPos blockpos = flag ? p_180614_3_ : p_180614_3_.func_177972_a(p_180614_5_); + ItemStack itemstack = p_180614_1_.func_184586_b(p_180614_4_); + +- if (p_180614_1_.func_175151_a(blockpos, p_180614_5_, itemstack) && p_180614_2_.func_190527_a(p_180614_2_.func_180495_p(blockpos).func_177230_c(), blockpos, false, p_180614_5_, (Entity)null) && Blocks.field_150488_af.func_176196_c(p_180614_2_, blockpos)) ++ if (p_180614_1_.func_175151_a(blockpos, p_180614_5_, itemstack) && p_180614_2_.func_190527_a(p_180614_2_.func_180495_p(blockpos).func_177230_c(), blockpos, false, p_180614_5_, p_180614_1_) && Blocks.field_150488_af.func_176196_c(p_180614_2_, blockpos)) + { + p_180614_2_.func_175656_a(blockpos, Blocks.field_150488_af.func_176223_P()); + diff --git a/patches/minecraft/net/minecraft/world/World.java.patch b/patches/minecraft/net/minecraft/world/World.java.patch index 3475b06610..062bbbc08d 100644 --- a/patches/minecraft/net/minecraft/world/World.java.patch +++ b/patches/minecraft/net/minecraft/world/World.java.patch @@ -899,16 +899,24 @@ } } -@@ -2958,7 +3178,7 @@ +@@ -2948,6 +3168,7 @@ + IBlockState iblockstate1 = this.func_180495_p(p_190527_2_); + AxisAlignedBB axisalignedbb = p_190527_3_ ? null : p_190527_1_.func_176223_P().func_185890_d(this, p_190527_2_); + ++ if (!((p_190527_5_ instanceof EntityPlayer) || !net.minecraftforge.event.ForgeEventFactory.onBlockPlace(p_190527_5_, new net.minecraftforge.common.util.BlockSnapshot(this, p_190527_2_, p_190527_1_.func_176223_P()), p_190527_4_).isCanceled())) return false; + if (axisalignedbb != Block.field_185506_k && !this.func_72917_a(axisalignedbb.func_186670_a(p_190527_2_), p_190527_5_)) + { + return false; +@@ -2958,7 +3179,7 @@ } else { - return iblockstate1.func_185904_a().func_76222_j() && p_190527_1_.func_176198_a(this, p_190527_2_, p_190527_4_); -+ return iblockstate1.func_177230_c().func_176200_f(this, p_190527_2_) && p_190527_1_.func_176198_a(this, p_190527_2_, p_190527_4_); ++ return iblockstate1.func_177230_c().func_176200_f(this, p_190527_2_); } } -@@ -3042,7 +3262,7 @@ +@@ -3042,7 +3263,7 @@ public int func_175651_c(BlockPos p_175651_1_, EnumFacing p_175651_2_) { IBlockState iblockstate1 = this.func_180495_p(p_175651_1_); @@ -917,7 +925,7 @@ } public boolean func_175640_z(BlockPos p_175640_1_) -@@ -3208,6 +3428,8 @@ +@@ -3208,6 +3429,8 @@ d2 *= ((Double)MoreObjects.firstNonNull(p_184150_11_.apply(entityplayer1), Double.valueOf(1.0D))).doubleValue(); } @@ -926,7 +934,7 @@ if ((p_184150_9_ < 0.0D || Math.abs(entityplayer1.field_70163_u - p_184150_3_) < p_184150_9_ * p_184150_9_) && (p_184150_7_ < 0.0D || d1 < d2 * d2) && (d0 == -1.0D || d1 < d0)) { d0 = d1; -@@ -3269,7 +3491,7 @@ +@@ -3269,7 +3492,7 @@ public long func_72905_C() { @@ -935,7 +943,7 @@ } public long func_82737_E() -@@ -3279,17 +3501,17 @@ +@@ -3279,17 +3502,17 @@ public long func_72820_D() { @@ -956,7 +964,7 @@ if (!this.func_175723_af().func_177746_a(blockpos1)) { -@@ -3301,7 +3523,7 @@ +@@ -3301,7 +3524,7 @@ public void func_175652_B(BlockPos p_175652_1_) { @@ -965,7 +973,7 @@ } @SideOnly(Side.CLIENT) -@@ -3321,12 +3543,18 @@ +@@ -3321,12 +3544,18 @@ if (!this.field_72996_f.contains(p_72897_1_)) { @@ -984,7 +992,7 @@ return true; } -@@ -3428,8 +3656,7 @@ +@@ -3428,8 +3657,7 @@ public boolean func_180502_D(BlockPos p_180502_1_) { @@ -994,7 +1002,7 @@ } @Nullable -@@ -3490,12 +3717,12 @@ +@@ -3490,12 +3718,12 @@ public int func_72800_K() { @@ -1009,7 +1017,7 @@ } public Random func_72843_D(int p_72843_1_, int p_72843_2_, int p_72843_3_) -@@ -3539,7 +3766,7 @@ +@@ -3539,7 +3767,7 @@ @SideOnly(Side.CLIENT) public double func_72919_O() { @@ -1018,7 +1026,7 @@ } public void func_175715_c(int p_175715_1_, BlockPos p_175715_2_, int p_175715_3_) -@@ -3573,7 +3800,7 @@ +@@ -3573,7 +3801,7 @@ public void func_175666_e(BlockPos p_175666_1_, Block p_175666_2_) { @@ -1027,7 +1035,7 @@ { BlockPos blockpos1 = p_175666_1_.func_177972_a(enumfacing); -@@ -3581,18 +3808,15 @@ +@@ -3581,18 +3809,15 @@ { IBlockState iblockstate1 = this.func_180495_p(blockpos1); @@ -1050,7 +1058,7 @@ } } } -@@ -3658,6 +3882,124 @@ +@@ -3658,6 +3883,124 @@ return j2 >= -128 && j2 <= 128 && k2 >= -128 && k2 <= 128; } diff --git a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java index 712b467748..2633e084ce 100644 --- a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java +++ b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java @@ -121,6 +121,8 @@ import net.minecraftforge.event.furnace.FurnaceFuelBurnTimeEvent; import net.minecraftforge.event.terraingen.ChunkGeneratorEvent; import net.minecraftforge.event.terraingen.PopulateChunkEvent; import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.event.world.BlockEvent.EntityMultiPlaceEvent; +import net.minecraftforge.event.world.BlockEvent.EntityPlaceEvent; import net.minecraftforge.event.world.BlockEvent.CreateFluidSourceEvent; import net.minecraftforge.event.world.BlockEvent.MultiPlaceEvent; import net.minecraftforge.event.world.BlockEvent.NeighborNotifyEvent; @@ -139,6 +141,15 @@ import javax.annotation.Nullable; public class ForgeEventFactory { + public static EntityMultiPlaceEvent onMultiBlockPlace(@Nullable Entity entity, List blockSnapshots, EnumFacing direction) + { + BlockSnapshot snap = blockSnapshots.get(0); + IBlockState placedAgainst = snap.getWorld().getBlockState(snap.getPos().offset(direction.getOpposite())); + EntityMultiPlaceEvent event = new EntityMultiPlaceEvent(blockSnapshots, placedAgainst, entity); + MinecraftForge.EVENT_BUS.post(event); + return event; + } + public static MultiPlaceEvent onPlayerMultiBlockPlace(EntityPlayer player, List blockSnapshots, EnumFacing direction, EnumHand hand) { BlockSnapshot snap = blockSnapshots.get(0); @@ -148,6 +159,15 @@ public class ForgeEventFactory return event; } + public static EntityPlaceEvent onBlockPlace(@Nullable Entity entity, @Nonnull BlockSnapshot blockSnapshot, @Nonnull EnumFacing direction) + { + IBlockState placedAgainst = blockSnapshot.getWorld().getBlockState(blockSnapshot.getPos().offset(direction.getOpposite())); + EntityPlaceEvent event = new BlockEvent.EntityPlaceEvent(blockSnapshot, placedAgainst, entity); + MinecraftForge.EVENT_BUS.post(event); + return event; + } + + public static PlaceEvent onPlayerBlockPlace(@Nonnull EntityPlayer player, @Nonnull BlockSnapshot blockSnapshot, @Nonnull EnumFacing direction, @Nonnull EnumHand hand) { IBlockState placedAgainst = blockSnapshot.getWorld().getBlockState(blockSnapshot.getPos().offset(direction.getOpposite())); diff --git a/src/main/java/net/minecraftforge/event/world/BlockEvent.java b/src/main/java/net/minecraftforge/event/world/BlockEvent.java index 2fe0359194..fa355ea401 100644 --- a/src/main/java/net/minecraftforge/event/world/BlockEvent.java +++ b/src/main/java/net/minecraftforge/event/world/BlockEvent.java @@ -22,13 +22,10 @@ package net.minecraftforge.event.world; import java.util.EnumSet; import java.util.List; -import net.minecraft.block.Block; import net.minecraft.block.BlockPortal; -import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Enchantments; import net.minecraft.item.ItemStack; @@ -44,6 +41,7 @@ import net.minecraftforge.fml.common.eventhandler.Event; import com.google.common.collect.ImmutableList; import javax.annotation.Nonnull; +import javax.annotation.Nullable; public class BlockEvent extends Event { @@ -165,26 +163,55 @@ public class BlockEvent extends Event } } + /** + * Called when a block is placed. + * + * If a Block Place event is cancelled, the block will not be placed. + */ + @Cancelable + public static class EntityPlaceEvent extends BlockEvent + { + private final Entity entity; + private final BlockSnapshot blockSnapshot; + private final IBlockState placedBlock; + private final IBlockState placedAgainst; + + public EntityPlaceEvent(@Nonnull BlockSnapshot blockSnapshot, @Nonnull IBlockState placedAgainst, @Nullable Entity entity) + { + super(blockSnapshot.getWorld(), blockSnapshot.getPos(), !(entity instanceof EntityPlayer) ? blockSnapshot.getReplacedBlock() : blockSnapshot.getCurrentBlock()); + this.entity = entity; + this.blockSnapshot = blockSnapshot; + this.placedBlock = !(entity instanceof EntityPlayer) ? blockSnapshot.getReplacedBlock() : blockSnapshot.getCurrentBlock(); + this.placedAgainst = placedAgainst; + + if (DEBUG) + { + System.out.printf("Created EntityPlaceEvent - [PlacedBlock: %s ][PlacedAgainst: %s ][Entity: %s ]\n", getPlacedBlock(), placedAgainst, entity); + } + } + + @Nullable + public Entity getEntity() { return entity; } + public BlockSnapshot getBlockSnapshot() { return blockSnapshot; } + public IBlockState getPlacedBlock() { return placedBlock; } + public IBlockState getPlacedAgainst() { return placedAgainst; } + } + /** * Called when a block is placed by a player. * * If a Block Place event is cancelled, the block will not be placed. */ @Cancelable - public static class PlaceEvent extends BlockEvent + @Deprecated // Remove in 1.13 + public static class PlaceEvent extends EntityPlaceEvent { private final EntityPlayer player; - private final BlockSnapshot blockSnapshot; - private final IBlockState placedBlock; - private final IBlockState placedAgainst; private final EnumHand hand; public PlaceEvent(@Nonnull BlockSnapshot blockSnapshot, @Nonnull IBlockState placedAgainst, @Nonnull EntityPlayer player, @Nonnull EnumHand hand) { - super(blockSnapshot.getWorld(), blockSnapshot.getPos(), blockSnapshot.getCurrentBlock()); + super(blockSnapshot, placedAgainst, player); this.player = player; - this.blockSnapshot = blockSnapshot; - this.placedBlock = blockSnapshot.getCurrentBlock(); - this.placedAgainst = placedAgainst; this.hand = hand; if (DEBUG) { @@ -196,12 +223,43 @@ public class BlockEvent extends Event @Nonnull @Deprecated public ItemStack getItemInHand() { return player.getHeldItem(hand); } - public BlockSnapshot getBlockSnapshot() { return blockSnapshot; } - public IBlockState getPlacedBlock() { return placedBlock; } - public IBlockState getPlacedAgainst() { return placedAgainst; } public EnumHand getHand() { return hand; } } + /** + * Fired when a single block placement triggers the + * creation of multiple blocks(e.g. placing a bed block). The block returned + * by {@link #state} and its related methods is the block where + * the placed block would exist if the placement only affected a single + * block. + */ + @Cancelable + public static class EntityMultiPlaceEvent extends EntityPlaceEvent + { + private final List blockSnapshots; + + public EntityMultiPlaceEvent(@Nonnull List blockSnapshots, @Nonnull IBlockState placedAgainst, @Nullable Entity entity) { + super(blockSnapshots.get(0), placedAgainst, entity); + this.blockSnapshots = ImmutableList.copyOf(blockSnapshots); + if (DEBUG) + { + System.out.printf("Created EntityMultiPlaceEvent - [PlacedAgainst: %s ][Entity: %s ]\n", placedAgainst, entity); + } + } + + /** + * Gets a list of BlockSnapshots for all blocks which were replaced by the + * placement of the new blocks. Most of these blocks will just be of type AIR. + * + * @return immutable list of replaced BlockSnapshots + */ + public List getReplacedBlockSnapshots() + { + return blockSnapshots; + } + } + + /** * Fired when a single block placement action of a player triggers the * creation of multiple blocks(e.g. placing a bed block). The block returned diff --git a/src/test/java/net/minecraftforge/debug/block/BasePlaceEventTest.java b/src/test/java/net/minecraftforge/debug/block/BasePlaceEventTest.java new file mode 100644 index 0000000000..ecb1bfe8a7 --- /dev/null +++ b/src/test/java/net/minecraftforge/debug/block/BasePlaceEventTest.java @@ -0,0 +1,46 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2018. + * + * 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.block; + +import net.minecraft.entity.item.EntityFallingBlock; +import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +@Mod(modid = BasePlaceEventTest.MOD_ID, name = "BaseBlockPlaceEvent test mod", version = "1.0", acceptableRemoteVersions = "*") +@Mod.EventBusSubscriber +public class BasePlaceEventTest +{ + static final String MOD_ID = "base_block_place_event_test"; + static final boolean ENABLED = true; + + @SubscribeEvent + public static void onBlockPlaced(BlockEvent.EntityPlaceEvent event) + { + if (!ENABLED) + { + return; + } + + if (event.getEntity() instanceof EntityFallingBlock) { + event.setCanceled(true); + } + } +}