diff --git a/src/main/java/org/ultramine/mods/bukkit/EventImplProgress.java b/src/main/java/org/ultramine/mods/bukkit/EventImplProgress.java index 0846949..6bbddae 100644 --- a/src/main/java/org/ultramine/mods/bukkit/EventImplProgress.java +++ b/src/main/java/org/ultramine/mods/bukkit/EventImplProgress.java @@ -72,7 +72,7 @@ reg(true, org.bukkit.event.block.BlockPistonRetractEvent.class); reg(true, org.bukkit.event.block.BlockPlaceEvent.class); reg(false, org.bukkit.event.block.BlockRedstoneEvent.class); - reg(false, org.bukkit.event.block.BlockSpreadEvent.class); + reg(true, org.bukkit.event.block.BlockSpreadEvent.class); reg(false, org.bukkit.event.block.EntityBlockFormEvent.class); reg(true, org.bukkit.event.block.LeavesDecayEvent.class); reg(true, org.bukkit.event.block.NotePlayEvent.class); diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockGrass.java b/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockGrass.java index f740f1f..3cfff05 100644 --- a/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockGrass.java +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockGrass.java @@ -6,11 +6,14 @@ import net.minecraft.world.World; import org.bukkit.block.BlockState; import org.bukkit.event.block.BlockFadeEvent; +import org.bukkit.event.block.BlockSpreadEvent; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; import org.ultramine.mods.bukkit.interfaces.world.IMixinWorld; +import java.util.Random; + @Mixin(BlockGrass.class) public class MixinBlockGrass { @@ -29,4 +32,17 @@ blockState.update(true); return false; } + + @Redirect(method = "updateTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlock(IIILnet/minecraft/block/Block;)Z", ordinal = 1)) + public boolean setBlockSpreadRedirect(World world, int x, int y, int z, Block block, World sourceWorld, int sourceX, int sourceY, int sourceZ, Random random) + { + org.bukkit.World bworld = ((IMixinWorld) world).getWorld(); + BlockState blockState = bworld.getBlockAt(x, y, z).getState(); + blockState.setTypeId(Block.getIdFromBlock(Blocks.grass)); + BlockSpreadEvent event = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(sourceX, sourceY, sourceZ), blockState); + ((IMixinWorld) world).getServer().getPluginManager().callEvent(event); + if (!event.isCancelled()) + blockState.update(true); + return false; + } } diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockMushroom.java b/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockMushroom.java new file mode 100644 index 0000000..304e87a --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockMushroom.java @@ -0,0 +1,30 @@ +package org.ultramine.mods.bukkit.mixin.block; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockMushroom; +import net.minecraft.world.World; +import org.bukkit.block.BlockState; +import org.bukkit.event.block.BlockSpreadEvent; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.ultramine.mods.bukkit.interfaces.world.IMixinWorld; + +import java.util.Random; + +@Mixin(BlockMushroom.class) +public abstract class MixinBlockMushroom +{ + @Redirect(method = "updateTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlock(IIILnet/minecraft/block/Block;II)Z")) + public boolean setBlockRedirect(World world, int x, int y, int z, Block block, int meta, int flags, World sourceWorld, int sourceX, int sourceY, int sourceZ, Random random) + { + org.bukkit.World bworld = ((IMixinWorld) world).getWorld(); + BlockState blockState = bworld.getBlockAt(x, y, z).getState(); + blockState.setTypeId(Block.getIdFromBlock((BlockMushroom)(Object) this)); // nms: this.id, 0, 2 + BlockSpreadEvent event = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(sourceX, sourceY, sourceZ), blockState); + ((IMixinWorld) world).getServer().getPluginManager().callEvent(event); + if (!event.isCancelled()) + blockState.update(true); + return false; + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockMycelium.java b/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockMycelium.java index 09acf05..6a69d6c 100644 --- a/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockMycelium.java +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockMycelium.java @@ -6,11 +6,14 @@ import net.minecraft.world.World; import org.bukkit.block.BlockState; import org.bukkit.event.block.BlockFadeEvent; +import org.bukkit.event.block.BlockSpreadEvent; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; import org.ultramine.mods.bukkit.interfaces.world.IMixinWorld; +import java.util.Random; + @Mixin(BlockMycelium.class) public class MixinBlockMycelium { @@ -18,7 +21,7 @@ * @author AtomicInteger */ @Redirect(method = "updateTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlock(IIILnet/minecraft/block/Block;)Z", ordinal = 0)) - public boolean setBlockRedirect(World world, int x, int y, int z, Block block) + public boolean setBlockFadeRedirect(World world, int x, int y, int z, Block block) { org.bukkit.World bworld = ((IMixinWorld) world).getWorld(); BlockState blockState = bworld.getBlockAt(x, y, z).getState(); @@ -29,4 +32,17 @@ blockState.update(true); return false; } + + @Redirect(method = "updateTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlock(IIILnet/minecraft/block/Block;)Z", ordinal = 1)) + public boolean setBlockSpreadRedirect(World world, int x, int y, int z, Block block, World sourceWorld, int sourceX, int sourceY, int sourceZ, Random random) + { + org.bukkit.World bworld = ((IMixinWorld) world).getWorld(); + BlockState blockState = bworld.getBlockAt(x, y, z).getState(); + blockState.setTypeId(Block.getIdFromBlock((BlockMycelium)(Object) this)); + BlockSpreadEvent event = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(sourceX, sourceY, sourceZ), blockState); + ((IMixinWorld) world).getServer().getPluginManager().callEvent(event); + if (!event.isCancelled()) + blockState.update(true); + return false; + } } diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockVine.java b/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockVine.java new file mode 100644 index 0000000..3475371 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockVine.java @@ -0,0 +1,138 @@ +package org.ultramine.mods.bukkit.mixin.block; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockVine; +import net.minecraft.block.material.Material; +import net.minecraft.util.Direction; +import net.minecraft.world.World; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; +import org.ultramine.mods.bukkit.interfaces.world.IMixinWorld; + +import java.util.Random; + +@Mixin(BlockVine.class) +public abstract class MixinBlockVine +{ + @Shadow protected abstract boolean func_150093_a(Block p_150093_1_); + + /** + * @author AtomicInteger + */ + @Overwrite + public void updateTick(World p_149674_1_, int p_149674_2_, int p_149674_3_, int p_149674_4_, Random p_149674_5_) + { + if (!p_149674_1_.isRemote && p_149674_1_.rand.nextInt(4) == 0) + { + BlockVine thisBlockVine = (BlockVine) (Object) this; + byte b0 = 4; + int l = 5; + boolean flag = false; + int i1; + int j1; + int k1; + label134: + for (i1 = p_149674_2_ - b0; i1 <= p_149674_2_ + b0; ++i1) + for (j1 = p_149674_4_ - b0; j1 <= p_149674_4_ + b0; ++j1) + for (k1 = p_149674_3_ - 1; k1 <= p_149674_3_ + 1; ++k1) + if (p_149674_1_.getBlock(i1, k1, j1) == thisBlockVine) + { + --l; + if (l <= 0) + { + flag = true; + break label134; + } + } + i1 = p_149674_1_.getBlockMetadata(p_149674_2_, p_149674_3_, p_149674_4_); + j1 = p_149674_1_.rand.nextInt(6); + k1 = Direction.facingToDirection[j1]; + int l1; + if (j1 == 1 && p_149674_3_ < 255 && p_149674_1_.isAirBlock(p_149674_2_, p_149674_3_ + 1, p_149674_4_)) + { + if (flag) + return; + int j2 = p_149674_1_.rand.nextInt(16) & i1; + if (j2 > 0) + { + for (l1 = 0; l1 <= 3; ++l1) + if (!this.func_150093_a(p_149674_1_.getBlock(p_149674_2_ + Direction.offsetX[l1], p_149674_3_ + 1, p_149674_4_ + Direction.offsetZ[l1]))) + j2 &= ~(1 << l1); + if (j2 > 0) + { + org.bukkit.block.Block source = ((IMixinWorld) p_149674_1_).getWorld().getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_); + org.bukkit.block.Block block = ((IMixinWorld) p_149674_1_).getWorld().getBlockAt(p_149674_2_, p_149674_3_ + 1, p_149674_4_); + CraftEventFactory.handleBlockSpreadEvent(block, source, thisBlockVine, l1); + } + } + } + else + { + Block block; + int i2; + if (j1 >= 2 && j1 <= 5 && (i1 & 1 << k1) == 0) + { + if (flag) + return; + block = p_149674_1_.getBlock(p_149674_2_ + Direction.offsetX[k1], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1]); + if (block.getMaterial() == Material.air) + { + l1 = k1 + 1 & 3; + i2 = k1 + 3 & 3; + org.bukkit.block.Block source = ((IMixinWorld) p_149674_1_).getWorld().getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_); + org.bukkit.block.Block bukkitBlock = ((IMixinWorld) p_149674_1_).getWorld().getBlockAt(p_149674_2_ + Direction.offsetX[k1], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1]); + if ((i1 & 1 << l1) != 0 && this.func_150093_a(p_149674_1_.getBlock(p_149674_2_ + Direction.offsetX[k1] + Direction.offsetX[l1], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1] + Direction.offsetZ[l1]))) + { + CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, thisBlockVine, 1 << l1); + } + else if ((i1 & 1 << i2) != 0 && this.func_150093_a(p_149674_1_.getBlock(p_149674_2_ + Direction.offsetX[k1] + Direction.offsetX[i2], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1] + Direction.offsetZ[i2]))) + { + CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, thisBlockVine, 1 << i2); + } + else if ((i1 & 1 << l1) != 0 && p_149674_1_.isAirBlock(p_149674_2_ + Direction.offsetX[k1] + Direction.offsetX[l1], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1] + Direction.offsetZ[l1]) && this.func_150093_a(p_149674_1_.getBlock(p_149674_2_ + Direction.offsetX[l1], p_149674_3_, p_149674_4_ + Direction.offsetZ[l1]))) + { + bukkitBlock = ((IMixinWorld) p_149674_1_).getWorld().getBlockAt(p_149674_2_ + Direction.offsetX[k1] + Direction.offsetX[l1], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1] + Direction.offsetZ[l1]); + CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, thisBlockVine, 1 << (k1 + 2 & 3)); + } + else if ((i1 & 1 << i2) != 0 && p_149674_1_.isAirBlock(p_149674_2_ + Direction.offsetX[k1] + Direction.offsetX[i2], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1] + Direction.offsetZ[i2]) && this.func_150093_a(p_149674_1_.getBlock(p_149674_2_ + Direction.offsetX[i2], p_149674_3_, p_149674_4_ + Direction.offsetZ[i2]))) + { + bukkitBlock = ((IMixinWorld) p_149674_1_).getWorld().getBlockAt(p_149674_2_ + Direction.offsetX[k1] + Direction.offsetX[i2], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1] + Direction.offsetZ[i2]); + CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, thisBlockVine, 1 << (k1 + 2 & 3)); + } + else if (this.func_150093_a(p_149674_1_.getBlock(p_149674_2_ + Direction.offsetX[k1], p_149674_3_ + 1, p_149674_4_ + Direction.offsetZ[k1]))) + { + CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, thisBlockVine, 0); + } + } + else if (block.getMaterial().isOpaque() && block.renderAsNormalBlock()) + { + p_149674_1_.setBlockMetadataWithNotify(p_149674_2_, p_149674_3_, p_149674_4_, i1 | 1 << k1, 2); + } + } + else if (p_149674_3_ > 1) + { + block = p_149674_1_.getBlock(p_149674_2_, p_149674_3_ - 1, p_149674_4_); + if (block.getMaterial() == Material.air) + { + l1 = p_149674_1_.rand.nextInt(16) & i1; + if (l1 > 0) + { + org.bukkit.block.Block source = ((IMixinWorld) p_149674_1_).getWorld().getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_); + org.bukkit.block.Block bukkitBlock = ((IMixinWorld) p_149674_1_).getWorld().getBlockAt(p_149674_2_, p_149674_3_ - 1, p_149674_4_); + CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, thisBlockVine, l1); + } + } + else if (block == thisBlockVine) + { + l1 = p_149674_1_.rand.nextInt(16) & i1; + i2 = p_149674_1_.getBlockMetadata(p_149674_2_, p_149674_3_ - 1, p_149674_4_); + if (i2 != (i2 | l1)) + p_149674_1_.setBlockMetadataWithNotify(p_149674_2_, p_149674_3_ - 1, p_149674_4_, i2 | l1, 2); + } + } + } + } + } +} diff --git a/src/main/resources/mixin.umbukkitimpl.json b/src/main/resources/mixin.umbukkitimpl.json index 92fef6a..40ed590 100644 --- a/src/main/resources/mixin.umbukkitimpl.json +++ b/src/main/resources/mixin.umbukkitimpl.json @@ -27,6 +27,8 @@ "block.MixinBlockReed", "block.MixinBlockStem", "block.MixinBlockPistonBase", + "block.MixinBlockMushroom", + "block.MixinBlockVine", "entity.MixinEntity", "entity.MixinEntityLiving", "entity.MixinEntityLivingBase",