--- a/net/minecraft/server/BlockFire.java +++ b/net/minecraft/server/BlockFire.java @@ -8,6 +8,16 @@ import java.util.function.Predicate; import javax.annotation.Nullable; +// CraftBukkit start + +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.block.CraftBlockState; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockFadeEvent; +import org.bukkit.event.block.BlockSpreadEvent; +// CraftBukkit end + public class BlockFire extends Block { public static final BlockStateInteger AGE = BlockProperties.X; @@ -32,7 +42,20 @@ } public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) { - return this.canPlace(iblockdata, generatoraccess, blockposition) ? (IBlockData) this.a((IBlockAccess) generatoraccess, blockposition).set(BlockFire.AGE, iblockdata.get(BlockFire.AGE)) : Blocks.AIR.getBlockData(); + // CraftBukkit start + if (!iblockdata.canPlace(generatoraccess, blockposition)) { + CraftBlockState blockState = CraftBlockState.getBlockState(generatoraccess, blockposition); + blockState.setData(Blocks.AIR.getBlockData()); + + BlockFadeEvent event = new BlockFadeEvent(blockState.getBlock(), blockState); + generatoraccess.getMinecraftWorld().getMinecraftServer().server.getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + return blockState.getHandle(); + } + } + return this.a((IBlockAccess) generatoraccess, blockposition).set(BlockFire.AGE, iblockdata.get(BlockFire.AGE)); + // CraftBukkit end } @Nullable @@ -82,7 +105,7 @@ public void a(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) { if (world.getGameRules().getBoolean("doFireTick")) { if (!iblockdata.canPlace(world, blockposition)) { - world.setAir(blockposition); + fireExtinguished(world, blockposition); // CraftBukkit - invalid place location } Block block = world.getType(blockposition.down()).getBlock(); @@ -90,7 +113,7 @@ int i = (Integer) iblockdata.get(BlockFire.AGE); if (!flag && world.isRaining() && this.a(world, blockposition) && random.nextFloat() < 0.2F + (float) i * 0.03F) { - world.setAir(blockposition); + fireExtinguished(world, blockposition); // CraftBukkit - extinguished by rain } else { int j = Math.min(15, i + random.nextInt(3) / 2); @@ -103,14 +126,14 @@ world.getBlockTickList().a(blockposition, this, this.a((IWorldReader) world) + random.nextInt(10)); if (!this.d(world, blockposition)) { if (!world.getType(blockposition.down()).q() || i > 3) { - world.setAir(blockposition); + fireExtinguished(world, blockposition); // CraftBukkit } return; } if (i == 15 && random.nextInt(4) == 0 && !this.k(world.getType(blockposition.down()))) { - world.setAir(blockposition); + fireExtinguished(world, blockposition); // CraftBukkit return; } } @@ -118,12 +141,14 @@ boolean flag1 = world.x(blockposition); int k = flag1 ? -50 : 0; - this.a(world, blockposition.east(), 300 + k, random, i); - this.a(world, blockposition.west(), 300 + k, random, i); - this.a(world, blockposition.down(), 250 + k, random, i); - this.a(world, blockposition.up(), 250 + k, random, i); - this.a(world, blockposition.north(), 300 + k, random, i); - this.a(world, blockposition.south(), 300 + k, random, i); + // CraftBukkit start - add source blockposition to burn calls + this.a(world, blockposition.east(), 300 + k, random, i, blockposition); + this.a(world, blockposition.west(), 300 + k, random, i, blockposition); + this.a(world, blockposition.down(), 250 + k, random, i, blockposition); + this.a(world, blockposition.up(), 250 + k, random, i, blockposition); + this.a(world, blockposition.north(), 300 + k, random, i, blockposition); + this.a(world, blockposition.south(), 300 + k, random, i, blockposition); + // CraftBukkit end BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); for (int l = -1; l <= 1; ++l) { @@ -149,7 +174,15 @@ if (i2 > 0 && random.nextInt(k1) <= i2 && (!world.isRaining() || !this.a(world, (BlockPosition) blockposition_mutableblockposition))) { int j2 = Math.min(15, i + random.nextInt(5) / 4); - world.setTypeAndData(blockposition_mutableblockposition, (IBlockData) this.a((IBlockAccess) world, (BlockPosition) blockposition_mutableblockposition).set(BlockFire.AGE, j2), 3); + // CraftBukkit start - Call to stop spread of fire + if (world.getType(blockposition_mutableblockposition) != Blocks.FIRE) { + if (CraftEventFactory.callBlockIgniteEvent(world, blockposition_mutableblockposition, blockposition).isCancelled()) { + continue; + } + + CraftEventFactory.handleBlockSpreadEvent(world, blockposition, blockposition_mutableblockposition, (IBlockData) this.a((IBlockAccess) world, (BlockPosition) blockposition_mutableblockposition).set(BlockFire.AGE, j2), 3); // CraftBukkit + } + // CraftBukkit end } } } @@ -173,12 +206,24 @@ return this.flameChances.getInt(block); } - private void a(World world, BlockPosition blockposition, int i, Random random, int j) { + private void a(World world, BlockPosition blockposition, int i, Random random, int j, BlockPosition sourceposition) { // CraftBukkit add sourceposition int k = this.f(world.getType(blockposition).getBlock()); if (random.nextInt(i) < k) { IBlockData iblockdata = world.getType(blockposition); + // CraftBukkit start + org.bukkit.block.Block theBlock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + org.bukkit.block.Block sourceBlock = world.getWorld().getBlockAt(sourceposition.getX(), sourceposition.getY(), sourceposition.getZ()); + + BlockBurnEvent event = new BlockBurnEvent(theBlock, sourceBlock); + world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return; + } + // CraftBukkit end + if (random.nextInt(j + 10) < 5 && !world.isRainingAt(blockposition)) { int l = Math.min(j + random.nextInt(5) / 4, 15); @@ -241,7 +286,7 @@ if (iblockdata1.getBlock() != iblockdata.getBlock()) { if (world.worldProvider.getDimensionManager() != DimensionManager.OVERWORLD && world.worldProvider.getDimensionManager() != DimensionManager.NETHER || !((BlockPortal) Blocks.NETHER_PORTAL).a((GeneratorAccess) world, blockposition)) { if (!iblockdata.canPlace(world, blockposition)) { - world.setAir(blockposition); + fireExtinguished(world, blockposition); // CraftBukkit - fuel block broke } else { world.getBlockTickList().a(blockposition, this, this.a((IWorldReader) world) + world.random.nextInt(10)); } @@ -387,4 +432,12 @@ blockfire.a(Blocks.BLACK_CARPET, 60, 20); blockfire.a(Blocks.DRIED_KELP_BLOCK, 30, 60); } + + // CraftBukkit start + private void fireExtinguished(GeneratorAccess world, BlockPosition position) { + if (!CraftEventFactory.callBlockFadeEvent(world, position, Blocks.AIR.getBlockData()).isCancelled()) { + world.setAir(position); + } + } + // CraftBukkit end }