diff --git a/patches/minecraft/net/minecraft/enchantment/EnchantmentFrostWalker.java.patch b/patches/minecraft/net/minecraft/enchantment/EnchantmentFrostWalker.java.patch index e0d935dfc..efdca145d 100644 --- a/patches/minecraft/net/minecraft/enchantment/EnchantmentFrostWalker.java.patch +++ b/patches/minecraft/net/minecraft/enchantment/EnchantmentFrostWalker.java.patch @@ -6,7 +6,7 @@ IBlockState iblockstate2 = p_185266_1_.func_180495_p(blockpos$mutableblockpos1); - if (iblockstate2.func_185904_a() == Material.field_151586_h && iblockstate2.func_177229_b(BlockFlowingFluid.field_176367_b) == 0 && iblockstate.func_196955_c(p_185266_1_, blockpos$mutableblockpos1) && p_185266_1_.func_195584_a(iblockstate, blockpos$mutableblockpos1)) { + boolean isFull = iblockstate2.func_177230_c() == Blocks.field_150355_j && iblockstate2.func_177229_b(BlockFlowingFluid.field_176367_b) == 0; //TODO: Forge, modded waters? -+ if (iblockstate2.func_185904_a() == Material.field_151586_h && isFull && iblockstate.func_196955_c(p_185266_1_, blockpos$mutableblockpos1) && p_185266_1_.func_195584_a(iblockstate, blockpos$mutableblockpos1)) { ++ if (iblockstate2.func_185904_a() == Material.field_151586_h && isFull && iblockstate.func_196955_c(p_185266_1_, blockpos$mutableblockpos1) && p_185266_1_.func_195584_a(iblockstate, blockpos$mutableblockpos1) && !net.minecraftforge.event.ForgeEventFactory.onBlockPlace(p_185266_0_, new net.minecraftforge.common.util.BlockSnapshot(p_185266_1_, blockpos$mutableblockpos1.func_185334_h(), iblockstate2), net.minecraft.util.EnumFacing.UP)) { p_185266_1_.func_175656_a(blockpos$mutableblockpos1, iblockstate); p_185266_1_.func_205220_G_().func_205360_a(blockpos$mutableblockpos1.func_185334_h(), Blocks.field_185778_de, MathHelper.func_76136_a(p_185266_0_.func_70681_au(), 60, 120)); } diff --git a/patches/minecraft/net/minecraft/entity/item/EntityFallingBlock.java.patch b/patches/minecraft/net/minecraft/entity/item/EntityFallingBlock.java.patch index 429491ed4..a98b6a7c8 100644 --- a/patches/minecraft/net/minecraft/entity/item/EntityFallingBlock.java.patch +++ b/patches/minecraft/net/minecraft/entity/item/EntityFallingBlock.java.patch @@ -8,7 +8,13 @@ if (!flag1 && BlockFalling.func_185759_i(this.field_70170_p.func_180495_p(new BlockPos(this.field_70165_t, this.field_70163_u - (double)0.01F, this.field_70161_v)))) { this.field_70122_E = false; return; -@@ -149,7 +150,7 @@ +@@ -144,12 +145,12 @@ + if (iblockstate.func_177230_c() != Blocks.field_196603_bb) { + this.func_70106_y(); + if (!this.field_145808_f) { +- if (iblockstate.func_185904_a().func_76222_j() && (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 (iblockstate.func_185904_a().func_76222_j() && (flag1 || !BlockFalling.func_185759_i(this.field_70170_p.func_180495_p(blockpos1.func_177977_b()))) && !net.minecraftforge.event.ForgeEventFactory.onBlockPlace(this, new net.minecraftforge.common.util.BlockSnapshot(func_130014_f_(), func_180425_c(), iblockstate), net.minecraft.util.EnumFacing.UP) && 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 b81071f61..e1c4e246a 100644 --- a/patches/minecraft/net/minecraft/entity/monster/EntityEnderman.java.patch +++ b/patches/minecraft/net/minecraft/entity/monster/EntityEnderman.java.patch @@ -20,6 +20,15 @@ return false; } else { return this.field_179475_a.func_70681_au().nextInt(2000) == 0; +@@ -373,7 +375,7 @@ + IBlockState iblockstate = iworld.func_180495_p(blockpos); + IBlockState iblockstate1 = iworld.func_180495_p(blockpos.func_177977_b()); + IBlockState iblockstate2 = this.field_179475_a.func_195405_dq(); +- if (iblockstate2 != null && this.func_195924_a(iworld, blockpos, iblockstate2, iblockstate, iblockstate1)) { ++ if (iblockstate2 != null && this.func_195924_a(iworld, blockpos, iblockstate2, iblockstate, iblockstate1) && !net.minecraftforge.event.ForgeEventFactory.onBlockPlace(field_179475_a, new net.minecraftforge.common.util.BlockSnapshot(field_179475_a.field_70170_p, blockpos, iblockstate), net.minecraft.util.EnumFacing.UP)) { + iworld.func_180501_a(blockpos, iblockstate2, 3); + this.field_179475_a.func_195406_b((IBlockState)null); + } @@ -395,7 +397,7 @@ public boolean func_75250_a() { if (this.field_179473_a.func_195405_dq() != null) { diff --git a/patches/minecraft/net/minecraft/item/BlockItemUseContext.java.patch b/patches/minecraft/net/minecraft/item/BlockItemUseContext.java.patch new file mode 100644 index 000000000..9ab96fadc --- /dev/null +++ b/patches/minecraft/net/minecraft/item/BlockItemUseContext.java.patch @@ -0,0 +1,19 @@ +--- a/net/minecraft/item/BlockItemUseContext.java ++++ b/net/minecraft/item/BlockItemUseContext.java +@@ -5,6 +5,7 @@ + import net.minecraft.util.EnumFacing; + import net.minecraft.util.math.BlockPos; + import net.minecraft.world.World; ++import net.minecraftforge.event.terraingen.BiomeEvent.GetGrassColor; + + public class BlockItemUseContext extends ItemUseContext { + private final BlockPos field_196014_j; +@@ -25,7 +26,7 @@ + } + + public boolean func_196011_b() { +- return this.field_196013_a || this.func_195991_k().func_180495_p(this.func_195995_a()).func_196953_a(this); ++ return (this.field_196013_a || this.func_195991_k().func_180495_p(this.func_195995_a()).func_196953_a(this)); + } + + public boolean func_196012_c() { diff --git a/patches/minecraft/net/minecraft/item/ItemBlock.java.patch b/patches/minecraft/net/minecraft/item/ItemBlock.java.patch index bf993477d..6ea816ff4 100644 --- a/patches/minecraft/net/minecraft/item/ItemBlock.java.patch +++ b/patches/minecraft/net/minecraft/item/ItemBlock.java.patch @@ -1,6 +1,18 @@ --- a/net/minecraft/item/ItemBlock.java +++ b/net/minecraft/item/ItemBlock.java -@@ -59,7 +59,7 @@ +@@ -40,9 +40,10 @@ + return EnumActionResult.FAIL; + } else { + IBlockState iblockstate = this.func_195945_b(p_195942_1_); ++ IBlockState currentState = p_195942_1_.func_195991_k().func_180495_p(p_195942_1_.func_195995_a()); + if (iblockstate == null) { + return EnumActionResult.FAIL; +- } else if (!this.func_195941_b(p_195942_1_, iblockstate)) { ++ } else if (!net.minecraftforge.event.ForgeEventFactory.onBlockPlace(p_195942_1_.func_195999_j(), new net.minecraftforge.common.util.BlockSnapshot(p_195942_1_.func_195991_k(), p_195942_1_.func_195995_a(), currentState), net.minecraft.util.EnumFacing.UP) && !this.func_195941_b(p_195942_1_, iblockstate)) { + return EnumActionResult.FAIL; + } else { + BlockPos blockpos = p_195942_1_.func_195995_a(); +@@ -59,7 +60,7 @@ } } @@ -9,7 +21,7 @@ world.func_184133_a(entityplayer, blockpos, soundtype.func_185841_e(), SoundCategory.BLOCKS, (soundtype.func_185843_a() + 1.0F) / 2.0F, soundtype.func_185847_b() * 0.8F); itemstack.func_190918_g(1); return EnumActionResult.SUCCESS; -@@ -134,6 +134,10 @@ +@@ -134,6 +135,10 @@ } public Block func_179223_d() { diff --git a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java index fefd54de5..18d2e2cd6 100644 --- a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java +++ b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java @@ -119,6 +119,8 @@ import net.minecraftforge.event.entity.player.UseHoeEvent; import net.minecraftforge.event.furnace.FurnaceFuelBurnTimeEvent; import net.minecraftforge.event.terraingen.ChunkGeneratorEvent; 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; @@ -133,6 +135,14 @@ import net.minecraftforge.eventbus.api.Event.Result; public class ForgeEventFactory { + public static boolean 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); + return MinecraftForge.EVENT_BUS.post(event); + } + public static MultiPlaceEvent onPlayerMultiBlockPlace(EntityPlayer player, List blockSnapshots, EnumFacing direction, EnumHand hand) { BlockSnapshot snap = blockSnapshots.get(0); @@ -142,6 +152,13 @@ public class ForgeEventFactory return event; } + public static boolean 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); + return MinecraftForge.EVENT_BUS.post(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 c57316045..e5496982b 100644 --- a/src/main/java/net/minecraftforge/event/world/BlockEvent.java +++ b/src/main/java/net/minecraftforge/event/world/BlockEvent.java @@ -43,6 +43,7 @@ import net.minecraftforge.eventbus.api.Event; import com.google.common.collect.ImmutableList; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import net.minecraftforge.eventbus.api.Event.HasResult; @@ -166,26 +167,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) { @@ -194,12 +224,46 @@ public class BlockEvent extends Event } public EntityPlayer getPlayer() { return player; } - public BlockSnapshot getBlockSnapshot() { return blockSnapshot; } - public IBlockState getPlacedBlock() { return placedBlock; } - public IBlockState getPlacedAgainst() { return placedAgainst; } + @Nonnull + @Deprecated + public ItemStack getItemInHand() { return player.getHeldItem(hand); } 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 000000000..ecb1bfe8a --- /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); + } + } +}