diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index 201c5e7..107ac3b 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -102,6 +102,7 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.messaging.StandardMessenger; import org.bukkit.util.Vector; +import org.ultramine.mods.bukkit.util.LightningEffectSwitcher; import org.ultramine.mods.bukkit.interfaces.IMixinEntityRegistry; import org.ultramine.mods.bukkit.interfaces.entity.IMixinEntity; import org.ultramine.mods.bukkit.interfaces.entity.projectile.IMixinEntityFireball; @@ -481,11 +482,11 @@ } public LightningStrike strikeLightningEffect(Location loc) - {//TODO - return null; -// net.minecraft.entity.effect.EntityLightningBolt lightning = new net.minecraft.entity.effect.EntityLightningBolt(world, loc.getX(), loc.getY(), loc.getZ(), true); -// world.addWeatherEffect(lightning); -// return new CraftLightningStrike(server, lightning); + { + LightningEffectSwitcher.isEffect = true; + net.minecraft.entity.effect.EntityLightningBolt lightning = new net.minecraft.entity.effect.EntityLightningBolt(world, loc.getX(), loc.getY(), loc.getZ()); + world.addWeatherEffect(lightning); + return new CraftLightningStrike(server, lightning); } public boolean generateTree(Location loc, TreeType type) diff --git a/src/main/java/org/ultramine/mods/bukkit/EventImplProgress.java b/src/main/java/org/ultramine/mods/bukkit/EventImplProgress.java index e1fac12..17ab454 100644 --- a/src/main/java/org/ultramine/mods/bukkit/EventImplProgress.java +++ b/src/main/java/org/ultramine/mods/bukkit/EventImplProgress.java @@ -65,7 +65,7 @@ reg(true, org.bukkit.event.block.BlockFormEvent.class); reg(true, org.bukkit.event.block.BlockFromToEvent.class); reg(true, org.bukkit.event.block.BlockGrowEvent.class); - reg(false, org.bukkit.event.block.BlockIgniteEvent.class); + reg(true, org.bukkit.event.block.BlockIgniteEvent.class); reg(false, org.bukkit.event.block.BlockMultiPlaceEvent.class); reg(false, org.bukkit.event.block.BlockPhysicsEvent.class); reg(false, org.bukkit.event.block.BlockPistonExtendEvent.class); diff --git a/src/main/java/org/ultramine/mods/bukkit/asm/ASMTransformer.java b/src/main/java/org/ultramine/mods/bukkit/asm/ASMTransformer.java new file mode 100644 index 0000000..ad18377 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/asm/ASMTransformer.java @@ -0,0 +1,15 @@ +package org.ultramine.mods.bukkit.asm; + +import net.minecraft.launchwrapper.IClassTransformer; +import org.ultramine.mods.bukkit.asm.transformers.LightningBoltConstructorTransformer; + +public class ASMTransformer implements IClassTransformer +{ + @Override + public byte[] transform(String name, String transformedName, byte[] basicClass) + { + if(transformedName.equals("net.minecraft.entity.effect.EntityLightningBolt")) + return LightningBoltConstructorTransformer.transformConstructor(basicClass); + return basicClass; + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/asm/UmBukkitCoremod.java b/src/main/java/org/ultramine/mods/bukkit/asm/UmBukkitCoremod.java index 73ec399..f724974 100644 --- a/src/main/java/org/ultramine/mods/bukkit/asm/UmBukkitCoremod.java +++ b/src/main/java/org/ultramine/mods/bukkit/asm/UmBukkitCoremod.java @@ -34,7 +34,7 @@ @Override public String[] getASMTransformerClass() { - return new String[0]; + return new String[] { "org.ultramine.mods.bukkit.asm.ASMTransformer" }; } @Override diff --git a/src/main/java/org/ultramine/mods/bukkit/asm/transformers/LightningBoltConstructorTransformer.java b/src/main/java/org/ultramine/mods/bukkit/asm/transformers/LightningBoltConstructorTransformer.java new file mode 100644 index 0000000..906c856 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/asm/transformers/LightningBoltConstructorTransformer.java @@ -0,0 +1,45 @@ +package org.ultramine.mods.bukkit.asm.transformers; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.InsnList; +import org.objectweb.asm.tree.InsnNode; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; +import org.objectweb.asm.tree.VarInsnNode; + +public class LightningBoltConstructorTransformer +{ + public static byte[] transformConstructor(byte[] targetClass) + { + ClassNode cNode = new ClassNode(); + new ClassReader(targetClass).accept(cNode, 0); + for (MethodNode mNode : cNode.methods) + if (mNode.name.equals("")) + { + mNode.instructions = getInsertInstructions(); + break; + } + ClassWriter cWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES); + cNode.accept(cWriter); + return cWriter.toByteArray(); + } + + private static InsnList getInsertInstructions() + { + InsnList newInstructions = new InsnList(); + newInstructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); + newInstructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); + newInstructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "net/minecraft/entity/effect/EntityWeatherEffect", "", "(Lnet/minecraft/world/World;)V", false)); + newInstructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); + newInstructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); + newInstructions.add(new VarInsnNode(Opcodes.DLOAD, 2)); + newInstructions.add(new VarInsnNode(Opcodes.DLOAD, 4)); + newInstructions.add(new VarInsnNode(Opcodes.DLOAD, 6)); + newInstructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "net/minecraft/entity/effect/EntityLightningBolt", "constructorInject", "(Lnet/minecraft/world/World;DDD)V", false)); + newInstructions.add(new InsnNode(Opcodes.RETURN)); + return newInstructions; + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockFire.java b/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockFire.java index 931ef38..e733b3e 100644 --- a/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockFire.java +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockFire.java @@ -1,12 +1,18 @@ package org.ultramine.mods.bukkit.mixin.block; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; import net.minecraft.init.Blocks; +import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockSpreadEvent; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; @@ -16,8 +22,13 @@ import java.util.Random; @Mixin(net.minecraft.block.BlockFire.class) -public class MixinBlockFire +public abstract class MixinBlockFire extends Block { + protected MixinBlockFire(Material p_i45394_1_) + { + super(p_i45394_1_); + } + @Inject(method = "tryCatchFire", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;getBlock(III)Lnet/minecraft/block/Block;", ordinal = 1)) private void onTryCatchFire(World w, int x, int y, int z, int r1, Random rng, int r2, ForgeDirection face, CallbackInfo ci) @@ -26,24 +37,13 @@ BlockBurnEvent event = new BlockBurnEvent(theBlock); Bukkit.getServer().getPluginManager().callEvent(event); - if(event.isCancelled()) + if (event.isCancelled()) { ci.cancel(); return; } } - /** - * @author AtomicInteger - */ - @Redirect(method = "updateTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockToAir(III)Z")) - public boolean setBlockAirUpdateTickRedirect(World world, int x, int y, int z) - { - if (!CraftEventFactory.callBlockFadeEvent(((IMixinWorld) world).getWorld().getBlockAt(x, y, z), Blocks.air).isCancelled()) - world.setBlockToAir(x, y, z); - return false; - } - @Redirect(method = "onNeighborBlockChange", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockToAir(III)Z")) public boolean setBlockToAirNeighborBlockChangeRedirect(World world, int x, int y, int z) { @@ -59,4 +59,124 @@ world.setBlockToAir(x, y, z); return false; } + + @Shadow + protected abstract void tryCatchFire(World p_149841_1_, int p_149841_2_, int p_149841_3_, int p_149841_4_, int p_149841_5_, Random p_149841_6_, int p_149841_7_, ForgeDirection face); + + @Shadow + protected abstract boolean canNeighborBurn(World p_149847_1_, int p_149847_2_, int p_149847_3_, int p_149847_4_); + + @Shadow + public abstract boolean canPlaceBlockAt(World p_149742_1_, int p_149742_2_, int p_149742_3_, int p_149742_4_); + + @Shadow + public abstract int tickRate(World p_149738_1_); + + @Shadow + public abstract boolean canCatchFire(IBlockAccess world, int x, int y, int z, ForgeDirection face); + + @Shadow + protected abstract int getChanceOfNeighborsEncouragingFire(World p_149845_1_, int p_149845_2_, int p_149845_3_, int p_149845_4_); + + /** + * @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_.getGameRules().getGameRuleBooleanValue("doFireTick")) + { + boolean flag = p_149674_1_.getBlock(p_149674_2_, p_149674_3_ - 1, p_149674_4_).isFireSource(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_, ForgeDirection.UP); + if (!this.canPlaceBlockAt(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_)) + { + if (!CraftEventFactory.callBlockFadeEvent(((IMixinWorld) p_149674_1_).getWorld().getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_), Blocks.air).isCancelled()) + p_149674_1_.setBlockToAir(p_149674_2_, p_149674_3_, p_149674_4_); + } + + if (!flag && p_149674_1_.isRaining() && (p_149674_1_.canLightningStrikeAt(p_149674_2_, p_149674_3_, p_149674_4_) || p_149674_1_.canLightningStrikeAt(p_149674_2_ - 1, p_149674_3_, p_149674_4_) || p_149674_1_.canLightningStrikeAt(p_149674_2_ + 1, p_149674_3_, p_149674_4_) || p_149674_1_.canLightningStrikeAt(p_149674_2_, p_149674_3_, p_149674_4_ - 1) || p_149674_1_.canLightningStrikeAt(p_149674_2_, p_149674_3_, p_149674_4_ + 1))) + { + if (!CraftEventFactory.callBlockFadeEvent(((IMixinWorld) p_149674_1_).getWorld().getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_), Blocks.air).isCancelled()) + p_149674_1_.setBlockToAir(p_149674_2_, p_149674_3_, p_149674_4_); + } + else + { + int l = p_149674_1_.getBlockMetadata(p_149674_2_, p_149674_3_, p_149674_4_); + if (l < 15) + p_149674_1_.setBlockMetadataWithNotify(p_149674_2_, p_149674_3_, p_149674_4_, l + p_149674_5_.nextInt(3) / 2, 4); + p_149674_1_.scheduleBlockUpdate(p_149674_2_, p_149674_3_, p_149674_4_, this, this.tickRate(p_149674_1_) + p_149674_5_.nextInt(10)); + if (!flag && !this.canNeighborBurn(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_)) + { + if (!World.doesBlockHaveSolidTopSurface(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_) || l > 3) + if (!CraftEventFactory.callBlockFadeEvent(((IMixinWorld) p_149674_1_).getWorld().getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_), Blocks.air).isCancelled()) + p_149674_1_.setBlockToAir(p_149674_2_, p_149674_3_, p_149674_4_); + } + else if (!flag && !this.canCatchFire(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_, ForgeDirection.UP) && l == 15 && p_149674_5_.nextInt(4) == 0) + { + if (!CraftEventFactory.callBlockFadeEvent(((IMixinWorld) p_149674_1_).getWorld().getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_), Blocks.air).isCancelled()) + p_149674_1_.setBlockToAir(p_149674_2_, p_149674_3_, p_149674_4_); + } + else + { + boolean flag1 = p_149674_1_.isBlockHighHumidity(p_149674_2_, p_149674_3_, p_149674_4_); + byte b0 = 0; + if (flag1) + b0 = -50; + this.tryCatchFire(p_149674_1_, p_149674_2_ + 1, p_149674_3_, p_149674_4_, 300 + b0, p_149674_5_, l, ForgeDirection.WEST); + this.tryCatchFire(p_149674_1_, p_149674_2_ - 1, p_149674_3_, p_149674_4_, 300 + b0, p_149674_5_, l, ForgeDirection.EAST); + this.tryCatchFire(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_, 250 + b0, p_149674_5_, l, ForgeDirection.UP); + this.tryCatchFire(p_149674_1_, p_149674_2_, p_149674_3_ + 1, p_149674_4_, 250 + b0, p_149674_5_, l, ForgeDirection.DOWN); + this.tryCatchFire(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_ - 1, 300 + b0, p_149674_5_, l, ForgeDirection.SOUTH); + this.tryCatchFire(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_ + 1, 300 + b0, p_149674_5_, l, ForgeDirection.NORTH); + for (int i1 = p_149674_2_ - 1; i1 <= p_149674_2_ + 1; ++i1) + for (int j1 = p_149674_4_ - 1; j1 <= p_149674_4_ + 1; ++j1) + for (int k1 = p_149674_3_ - 1; k1 <= p_149674_3_ + 4; ++k1) + if (i1 != p_149674_2_ || k1 != p_149674_3_ || j1 != p_149674_4_) + { + int l1 = 100; + if (k1 > p_149674_3_ + 1) + { + l1 += (k1 - (p_149674_3_ + 1)) * 100; + } + + int i2 = this.getChanceOfNeighborsEncouragingFire(p_149674_1_, i1, k1, j1); + if (i2 > 0) + { + int j2 = (i2 + 40 + p_149674_1_.difficultySetting.getDifficultyId() * 7) / (l + 30); + if (flag1) + { + j2 /= 2; + } + + if (j2 > 0 && p_149674_5_.nextInt(l1) <= j2 && (!p_149674_1_.isRaining() || !p_149674_1_.canLightningStrikeAt(i1, k1, j1)) && !p_149674_1_.canLightningStrikeAt(i1 - 1, k1, p_149674_4_) && !p_149674_1_.canLightningStrikeAt(i1 + 1, k1, j1) && !p_149674_1_.canLightningStrikeAt(i1, k1, j1 - 1) && !p_149674_1_.canLightningStrikeAt(i1, k1, j1 + 1)) + { + int k2 = l + p_149674_5_.nextInt(5) / 4; + if (k2 > 15) + { + k2 = 15; + } + + if (p_149674_1_.getBlock(i1, k1, j1) != Blocks.fire) + { + if (CraftEventFactory.callBlockIgniteEvent(p_149674_1_, i1, k1, j1, p_149674_2_, p_149674_3_, p_149674_4_).isCancelled()) + continue; + org.bukkit.Server server = ((IMixinWorld) p_149674_1_).getServer(); + org.bukkit.World bworld = ((IMixinWorld) p_149674_1_).getWorld(); + org.bukkit.block.BlockState blockState = bworld.getBlockAt(i1, k1, j1).getState(); + blockState.setTypeId(Block.getIdFromBlock(this)); + blockState.setData(new org.bukkit.material.MaterialData(Block.getIdFromBlock(this), (byte) k2)); + BlockSpreadEvent spreadEvent = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_), blockState); + server.getPluginManager().callEvent(spreadEvent); + if (!spreadEvent.isCancelled()) + { + p_149674_1_.setBlock(i1, k1, j1, ((org.bukkit.craftbukkit.block.CraftBlock) blockState.getBlock()).getNMSBlock(), blockState.getRawData(), 3); // KCauldron - DragonAPI uses this call + blockState.update(true); + } + } + } + } + } + } + } + } + } } diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockStaticLiquid.java b/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockStaticLiquid.java new file mode 100644 index 0000000..291b0d7 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockStaticLiquid.java @@ -0,0 +1,80 @@ +package org.ultramine.mods.bukkit.mixin.block; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockStaticLiquid; +import net.minecraft.block.material.Material; +import net.minecraft.init.Blocks; +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 java.util.Random; + +@Mixin(BlockStaticLiquid.class) +public abstract class MixinBlockStaticLiquid +{ + @Shadow protected abstract boolean isFlammable(World p_149817_1_, int p_149817_2_, int p_149817_3_, int p_149817_4_); + + /** + * @author AtomicInteger + */ + @Overwrite + public void updateTick(World world, int x, int y, int z, Random random) + { + if (((BlockStaticLiquid) (Object) this).getMaterial() == Material.lava) + { + int l = random.nextInt(3); + int i1 = 0; + int igniterX = x; + int igniterY = y; + int igniterZ = z; + while (true) + { + if (i1 >= l) + { + if (l == 0) + { + i1 = x; + int k1 = z; + + for (int j1 = 0; j1 < 3; ++j1) + { + x = i1 + random.nextInt(3) - 1; + z = k1 + random.nextInt(3) - 1; + if (world.isAirBlock(x, y + 1, z) && this.isFlammable(world, x, y, z)) + { + if (world.getBlock(x, y + 1, z) != Blocks.fire) + if (CraftEventFactory.callBlockIgniteEvent(world, x, y + 1, z, igniterX, igniterY, igniterZ).isCancelled()) + continue; + world.setBlock(x, y + 1, z, Blocks.fire); + } + } + } + break; + } + x += random.nextInt(3) - 1; + ++y; + z += random.nextInt(3) - 1; + Block block = world.getBlock(x, y, z); + if (block.getMaterial() == Material.air) + { + if (this.isFlammable(world, x - 1, y, z) || this.isFlammable(world, x + 1, y, z) || this.isFlammable(world, x, y, z - 1) || this.isFlammable(world, x, y, z + 1) || this.isFlammable(world, x, y - 1, z) || this.isFlammable(world, x, y + 1, z)) + { + if (world.getBlock(x, y, z) != Blocks.fire) + if (CraftEventFactory.callBlockIgniteEvent(world, x, y, z, igniterX, igniterY, igniterZ).isCancelled()) + continue; + world.setBlock(x, y, z, Blocks.fire); + return; + } + } + else if (block.getMaterial().blocksMovement()) + { + return; + } + ++i1; + } + } + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/entity/effect/MixinEntityLightningBolt.java b/src/main/java/org/ultramine/mods/bukkit/mixin/entity/effect/MixinEntityLightningBolt.java new file mode 100644 index 0000000..2391522 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/entity/effect/MixinEntityLightningBolt.java @@ -0,0 +1,135 @@ +package org.ultramine.mods.bukkit.mixin.entity.effect; + +import net.minecraft.block.material.Material; +import net.minecraft.entity.Entity; +import net.minecraft.entity.effect.EntityLightningBolt; +import net.minecraft.entity.effect.EntityWeatherEffect; +import net.minecraft.init.Blocks; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.MathHelper; +import net.minecraft.world.EnumDifficulty; +import net.minecraft.world.World; +import net.minecraftforge.event.ForgeEventFactory; +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.util.LightningEffectSwitcher; + +import java.util.List; + +@Mixin(EntityLightningBolt.class) +public class MixinEntityLightningBolt extends EntityWeatherEffect +{ + public MixinEntityLightningBolt(World p_i1702_1_) + { + super(p_i1702_1_); + } + + @Shadow private int lightningState; + + @Shadow public long boltVertex; + + @Shadow private int boltLivingTime; + + public void constructorInject(World p_i1703_1_, double p_i1703_2_, double p_i1703_4_, double p_i1703_6_) + { + this.setLocationAndAngles(p_i1703_2_, p_i1703_4_, p_i1703_6_, 0.0F, 0.0F); + this.lightningState = 2; + this.boltVertex = this.rand.nextLong(); + this.boltLivingTime = this.rand.nextInt(3) + 1; + if (!LightningEffectSwitcher.isEffect && !p_i1703_1_.isRemote && p_i1703_1_.getGameRules().getGameRuleBooleanValue("doFireTick") && (p_i1703_1_.difficultySetting == EnumDifficulty.NORMAL || p_i1703_1_.difficultySetting == EnumDifficulty.HARD) && p_i1703_1_.doChunksNearChunkExist(MathHelper.floor_double(p_i1703_2_), MathHelper.floor_double(p_i1703_4_), MathHelper.floor_double(p_i1703_6_), 10)) + { + int i = MathHelper.floor_double(p_i1703_2_); + int j = MathHelper.floor_double(p_i1703_4_); + int k = MathHelper.floor_double(p_i1703_6_); + if (p_i1703_1_.getBlock(i, j, k).getMaterial() == Material.air && Blocks.fire.canPlaceBlockAt(p_i1703_1_, i, j, k)) + if (!CraftEventFactory.callBlockIgniteEvent(p_i1703_1_, i, j, k, this).isCancelled()) + p_i1703_1_.setBlock(i, j, k, Blocks.fire); + for (i = 0; i < 4; ++i) + { + j = MathHelper.floor_double(p_i1703_2_) + this.rand.nextInt(3) - 1; + k = MathHelper.floor_double(p_i1703_4_) + this.rand.nextInt(3) - 1; + int l = MathHelper.floor_double(p_i1703_6_) + this.rand.nextInt(3) - 1; + if (p_i1703_1_.getBlock(j, k, l).getMaterial() == Material.air && Blocks.fire.canPlaceBlockAt(p_i1703_1_, j, k, l)) + if (!CraftEventFactory.callBlockIgniteEvent(p_i1703_1_, j, k, l, this).isCancelled()) + p_i1703_1_.setBlock(j, k, l, Blocks.fire); + } + } + LightningEffectSwitcher.isEffect = false; + } + + /** + * @author AtomicInteger + */ + @Overwrite + public void onUpdate() + { + super.onUpdate(); + if (this.lightningState == 2) + { + this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "ambient.weather.thunder", 10000.0F, 0.8F + this.rand.nextFloat() * 0.2F); + this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "random.explode", 2.0F, 0.5F + this.rand.nextFloat() * 0.2F); + } + --this.lightningState; + if (this.lightningState < 0) + { + if (this.boltLivingTime == 0) + { + this.setDead(); + } + else if (this.lightningState < -this.rand.nextInt(10)) + { + --this.boltLivingTime; + this.lightningState = 1; + this.boltVertex = this.rand.nextLong(); + if (!LightningEffectSwitcher.isEffect && !this.worldObj.isRemote && this.worldObj.getGameRules().getGameRuleBooleanValue("doFireTick") && this.worldObj.doChunksNearChunkExist(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ), 10)) + { + int i = MathHelper.floor_double(this.posX); + int j = MathHelper.floor_double(this.posY); + int k = MathHelper.floor_double(this.posZ); + if (this.worldObj.getBlock(i, j, k).getMaterial() == Material.air && Blocks.fire.canPlaceBlockAt(this.worldObj, i, j, k)) + if (!CraftEventFactory.callBlockIgniteEvent(worldObj, i, j, k, this).isCancelled()) + this.worldObj.setBlock(i, j, k, Blocks.fire); + } + } + } + if (this.lightningState >= 0 && !LightningEffectSwitcher.isEffect) + { + if (this.worldObj.isRemote) + { + this.worldObj.lastLightningBolt = 2; + } + else + { + double d0 = 3.0D; + List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, AxisAlignedBB.getBoundingBox(this.posX - d0, this.posY - d0, this.posZ - d0, this.posX + d0, this.posY + 6.0D + d0, this.posZ + d0)); + for (Object aList : list) + { + Entity entity = (Entity) aList; + if (!ForgeEventFactory.onEntityStruckByLightning(entity, (EntityLightningBolt) (Object) this)) + entity.onStruckByLightning((EntityLightningBolt) (Object) this); + } + } + } + } + + @Override + protected void entityInit() + { + + } + + @Override + protected void readEntityFromNBT(NBTTagCompound nbtTagCompound) + { + + } + + @Override + protected void writeEntityToNBT(NBTTagCompound nbtTagCompound) + { + + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/entity/item/MixinEntityEnderCrystal.java b/src/main/java/org/ultramine/mods/bukkit/mixin/entity/item/MixinEntityEnderCrystal.java index b6f7a23..c7e8e0e 100644 --- a/src/main/java/org/ultramine/mods/bukkit/mixin/entity/item/MixinEntityEnderCrystal.java +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/entity/item/MixinEntityEnderCrystal.java @@ -1,12 +1,16 @@ package org.ultramine.mods.bukkit.mixin.entity.item; import com.avaje.ebean.enhance.asm.Opcodes; +import net.minecraft.block.Block; import net.minecraft.entity.item.EntityEnderCrystal; +import net.minecraft.init.Blocks; import net.minecraft.util.DamageSource; +import net.minecraft.world.World; import org.bukkit.craftbukkit.event.CraftEventFactory; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(net.minecraft.entity.item.EntityEnderCrystal.class) @@ -18,4 +22,12 @@ if(CraftEventFactory.handleNonLivingEntityDamageEvent((EntityEnderCrystal) (Object) this, p_70097_1_, p_70097_2_)) ci.setReturnValue(false); } + + @Redirect(method = "onUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlock(IIILnet/minecraft/block/Block;)Z")) + public boolean setBlockRedirect(World world, int x, int y, int z, Block block) + { + if (!CraftEventFactory.callBlockIgniteEvent(world, x, y, z, (EntityEnderCrystal) (Object) this).isCancelled()) + world.setBlock(x, y, z, Blocks.fire); + return false; + } } diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/entity/projectile/MixinEntitySmallFireball.java b/src/main/java/org/ultramine/mods/bukkit/mixin/entity/projectile/MixinEntitySmallFireball.java new file mode 100644 index 0000000..c60da12 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/entity/projectile/MixinEntitySmallFireball.java @@ -0,0 +1,21 @@ +package org.ultramine.mods.bukkit.mixin.entity.projectile; + +import net.minecraft.block.Block; +import net.minecraft.entity.projectile.EntitySmallFireball; +import net.minecraft.init.Blocks; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(EntitySmallFireball.class) +public class MixinEntitySmallFireball +{ + @Redirect(method = "onImpact", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlock(IIILnet/minecraft/block/Block;)Z")) + public boolean setBlockRedirect(World world, int x, int y, int z, Block block) + { + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, x, y, z, (EntitySmallFireball) (Object) this).isCancelled()) + world.setBlock(x, y, z, Blocks.fire); + return false; + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/init/MixinBootstrapFireCharge.java b/src/main/java/org/ultramine/mods/bukkit/mixin/init/MixinBootstrapFireCharge.java index 5fee311..a0b07e2 100644 --- a/src/main/java/org/ultramine/mods/bukkit/mixin/init/MixinBootstrapFireCharge.java +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/init/MixinBootstrapFireCharge.java @@ -60,7 +60,6 @@ EntitySmallFireball entitysmallfireball = new EntitySmallFireball(world, d0, d1, d2, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ()); ((IMixinEntity) entitysmallfireball).setProjectileSource(new org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource((TileEntityDispenser) blockSource.getBlockTileEntity())); world.spawnEntityInWorld(entitysmallfireball); - itemStack.splitStack(1); return itemStack; } } diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/init/MixinBootstrapFireworks.java b/src/main/java/org/ultramine/mods/bukkit/mixin/init/MixinBootstrapFireworks.java index 5c56118..c9f2fc1 100644 --- a/src/main/java/org/ultramine/mods/bukkit/mixin/init/MixinBootstrapFireworks.java +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/init/MixinBootstrapFireworks.java @@ -51,7 +51,6 @@ itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); EntityFireworkRocket entityfireworkrocket = new EntityFireworkRocket(blockSource.getWorld(), event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), itemstack1); blockSource.getWorld().spawnEntityInWorld(entityfireworkrocket); - itemStack.splitStack(1); return itemStack; } } diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/init/MixinBootstrapLavaBucket.java b/src/main/java/org/ultramine/mods/bukkit/mixin/init/MixinBootstrapLavaBucket.java deleted file mode 100644 index 0f56641..0000000 --- a/src/main/java/org/ultramine/mods/bukkit/mixin/init/MixinBootstrapLavaBucket.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.ultramine.mods.bukkit.mixin.init; - -import net.minecraft.block.BlockDispenser; -import net.minecraft.dispenser.BehaviorDefaultDispenseItem; -import net.minecraft.dispenser.IBehaviorDispenseItem; -import net.minecraft.dispenser.IBlockSource; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.item.ItemBucket; -import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntityDispenser; -import net.minecraft.util.EnumFacing; -import net.minecraft.world.World; -import org.bukkit.craftbukkit.inventory.CraftItemStack; -import org.bukkit.event.block.BlockDispenseEvent; -import org.spongepowered.asm.mixin.Final; -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; - -@Mixin(targets = "net/minecraft/init/Bootstrap$10") -public class MixinBootstrapLavaBucket -{ - @Final - @Shadow private BehaviorDefaultDispenseItem field_150841_b; - - /** - * @author AtomicInteger - */ - @Overwrite - public ItemStack dispenseStack(IBlockSource blockSource, ItemStack itemStack) - { - ItemBucket itembucket = (ItemBucket) itemStack.getItem(); - int i = blockSource.getXInt(); - int j = blockSource.getYInt(); - int k = blockSource.getZInt(); - EnumFacing enumfacing = BlockDispenser.func_149937_b(blockSource.getBlockMetadata()); - World world = blockSource.getWorld(); - int x = i + enumfacing.getFrontOffsetX(); - int y = j + enumfacing.getFrontOffsetY(); - int z = k + enumfacing.getFrontOffsetZ(); - if (world.isAirBlock(x, y, z) || !world.getBlock(x, y, z).getMaterial().isSolid()) - { - org.bukkit.block.Block block = ((IMixinWorld) world).getWorld().getBlockAt(i, j, k); - CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemStack); - BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(x, y, z)); - ((IMixinWorld) world).getServer().getPluginManager().callEvent(event); - if (event.isCancelled()) - return itemStack; - if (!event.getItem().equals(craftItem)) - { - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - IBehaviorDispenseItem ibehaviordispenseitem = (IBehaviorDispenseItem) BlockDispenser.dispenseBehaviorRegistry.getObject(eventStack.getItem()); - if (ibehaviordispenseitem != IBehaviorDispenseItem.itemDispenseBehaviorProvider && ibehaviordispenseitem != this) - { - ibehaviordispenseitem.dispense(blockSource, eventStack); - return itemStack; - } - } - itembucket = (ItemBucket) CraftItemStack.asNMSCopy(event.getItem()).getItem(); - } - if (itembucket.tryPlaceContainedLiquid(blockSource.getWorld(), i + enumfacing.getFrontOffsetX(), j + enumfacing.getFrontOffsetY(), k + enumfacing.getFrontOffsetZ())) - { - Item item = Items.bucket; - if (--itemStack.stackSize == 0) - { - itemStack.func_150996_a(Items.bucket); - itemStack.stackSize = 1; - } - else if (((TileEntityDispenser) blockSource.getBlockTileEntity()).func_146019_a(new ItemStack(item)) < 0) - { - this.field_150841_b.dispense(blockSource, new ItemStack(item)); - } - return itemStack; - } - else - { - return this.field_150841_b.dispense(blockSource, itemStack); - } - } -} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/init/MixinBootstrapWaterBucket.java b/src/main/java/org/ultramine/mods/bukkit/mixin/init/MixinBootstrapWaterBucket.java deleted file mode 100644 index 5fa9520..0000000 --- a/src/main/java/org/ultramine/mods/bukkit/mixin/init/MixinBootstrapWaterBucket.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.ultramine.mods.bukkit.mixin.init; - -import net.minecraft.block.BlockDispenser; -import net.minecraft.dispenser.BehaviorDefaultDispenseItem; -import net.minecraft.dispenser.IBehaviorDispenseItem; -import net.minecraft.dispenser.IBlockSource; -import net.minecraft.init.Items; -import net.minecraft.item.Item; -import net.minecraft.item.ItemBucket; -import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.TileEntityDispenser; -import net.minecraft.util.EnumFacing; -import net.minecraft.world.World; -import org.bukkit.craftbukkit.inventory.CraftItemStack; -import org.bukkit.event.block.BlockDispenseEvent; -import org.spongepowered.asm.mixin.Final; -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; - -@Mixin(targets = "net/minecraft/init/Bootstrap$10") -public class MixinBootstrapWaterBucket -{ - @Final - @Shadow private BehaviorDefaultDispenseItem field_150841_b; - - /** - * @author AtomicInteger - */ - @Overwrite - public ItemStack dispenseStack(IBlockSource blockSource, ItemStack itemStack) - { - ItemBucket itembucket = (ItemBucket) itemStack.getItem(); - int i = blockSource.getXInt(); - int j = blockSource.getYInt(); - int k = blockSource.getZInt(); - EnumFacing enumfacing = BlockDispenser.func_149937_b(blockSource.getBlockMetadata()); - World world = blockSource.getWorld(); - int x = i + enumfacing.getFrontOffsetX(); - int y = j + enumfacing.getFrontOffsetY(); - int z = k + enumfacing.getFrontOffsetZ(); - if (world.isAirBlock(x, y, z) || !world.getBlock(x, y, z).getMaterial().isSolid()) - { - org.bukkit.block.Block block = ((IMixinWorld) world).getWorld().getBlockAt(i, j, k); - CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemStack); - BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(x, y, z)); - ((IMixinWorld) world).getServer().getPluginManager().callEvent(event); - if (event.isCancelled()) - return itemStack; - if (!event.getItem().equals(craftItem)) - { - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - IBehaviorDispenseItem ibehaviordispenseitem = (IBehaviorDispenseItem) BlockDispenser.dispenseBehaviorRegistry.getObject(eventStack.getItem()); - if (ibehaviordispenseitem != IBehaviorDispenseItem.itemDispenseBehaviorProvider && ibehaviordispenseitem != this) - { - ibehaviordispenseitem.dispense(blockSource, eventStack); - return itemStack; - } - } - itembucket = (ItemBucket) CraftItemStack.asNMSCopy(event.getItem()).getItem(); - } - if (itembucket.tryPlaceContainedLiquid(blockSource.getWorld(), i + enumfacing.getFrontOffsetX(), j + enumfacing.getFrontOffsetY(), k + enumfacing.getFrontOffsetZ())) - { - Item item = Items.bucket; - if (--itemStack.stackSize == 0) - { - itemStack.func_150996_a(Items.bucket); - itemStack.stackSize = 1; - } - else if (((TileEntityDispenser) blockSource.getBlockTileEntity()).func_146019_a(new ItemStack(item)) < 0) - { - this.field_150841_b.dispense(blockSource, new ItemStack(item)); - } - return itemStack; - } - else - { - return this.field_150841_b.dispense(blockSource, itemStack); - } - } -} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/init/MixinBootstrapWaterLavaBucket.java b/src/main/java/org/ultramine/mods/bukkit/mixin/init/MixinBootstrapWaterLavaBucket.java new file mode 100644 index 0000000..7cb3dde --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/init/MixinBootstrapWaterLavaBucket.java @@ -0,0 +1,82 @@ +package org.ultramine.mods.bukkit.mixin.init; + +import net.minecraft.block.BlockDispenser; +import net.minecraft.dispenser.BehaviorDefaultDispenseItem; +import net.minecraft.dispenser.IBehaviorDispenseItem; +import net.minecraft.dispenser.IBlockSource; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBucket; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntityDispenser; +import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.block.BlockDispenseEvent; +import org.spongepowered.asm.mixin.Final; +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; + +@Mixin(targets = "net/minecraft/init/Bootstrap$10") +public class MixinBootstrapWaterLavaBucket +{ + @Final + @Shadow private BehaviorDefaultDispenseItem field_150841_b; + + /** + * @author AtomicInteger + */ + @Overwrite + public ItemStack dispenseStack(IBlockSource blockSource, ItemStack itemStack) + { + ItemBucket itembucket = (ItemBucket) itemStack.getItem(); + int i = blockSource.getXInt(); + int j = blockSource.getYInt(); + int k = blockSource.getZInt(); + EnumFacing enumfacing = BlockDispenser.func_149937_b(blockSource.getBlockMetadata()); + World world = blockSource.getWorld(); + int x = i + enumfacing.getFrontOffsetX(); + int y = j + enumfacing.getFrontOffsetY(); + int z = k + enumfacing.getFrontOffsetZ(); + if (world.isAirBlock(x, y, z) || !world.getBlock(x, y, z).getMaterial().isSolid()) + { + org.bukkit.block.Block block = ((IMixinWorld) world).getWorld().getBlockAt(i, j, k); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemStack); + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(x, y, z)); + ((IMixinWorld) world).getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) + return itemStack; + if (!event.getItem().equals(craftItem)) + { + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IBehaviorDispenseItem ibehaviordispenseitem = (IBehaviorDispenseItem) BlockDispenser.dispenseBehaviorRegistry.getObject(eventStack.getItem()); + if (ibehaviordispenseitem != IBehaviorDispenseItem.itemDispenseBehaviorProvider && ibehaviordispenseitem != this) + { + ibehaviordispenseitem.dispense(blockSource, eventStack); + return itemStack; + } + } + itembucket = (ItemBucket) CraftItemStack.asNMSCopy(event.getItem()).getItem(); + } + if (itembucket.tryPlaceContainedLiquid(blockSource.getWorld(), i + enumfacing.getFrontOffsetX(), j + enumfacing.getFrontOffsetY(), k + enumfacing.getFrontOffsetZ())) + { + Item item = Items.bucket; + if (--itemStack.stackSize == 0) + { + itemStack.func_150996_a(Items.bucket); + itemStack.stackSize = 1; + } + else if (((TileEntityDispenser) blockSource.getBlockTileEntity()).func_146019_a(new ItemStack(item)) < 0) + { + this.field_150841_b.dispense(blockSource, new ItemStack(item)); + } + return itemStack; + } + else + { + return this.field_150841_b.dispense(blockSource, itemStack); + } + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/item/MixinItemFireball.java b/src/main/java/org/ultramine/mods/bukkit/mixin/item/MixinItemFireball.java new file mode 100644 index 0000000..5c8a867 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/item/MixinItemFireball.java @@ -0,0 +1,27 @@ +package org.ultramine.mods.bukkit.mixin.item; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemFireball; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import org.bukkit.event.block.BlockIgniteEvent; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(ItemFireball.class) +public class MixinItemFireball +{ + @Inject(method = "onItemUse", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;playSoundEffect(DDDLjava/lang/String;FF)V", shift = Shift.BEFORE)) + public void onItemUseInject(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int p_77648_7_, float p_77648_8_, float p_77648_9_, float p_77648_10_, CallbackInfoReturnable cir) + { + if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, x, y, z, BlockIgniteEvent.IgniteCause.FIREBALL, player).isCancelled()) + { + if (!player.capabilities.isCreativeMode) + --itemStack.stackSize; + cir.setReturnValue(false); + } + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/util/LightningEffectSwitcher.java b/src/main/java/org/ultramine/mods/bukkit/util/LightningEffectSwitcher.java new file mode 100644 index 0000000..5c4c1c9 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/util/LightningEffectSwitcher.java @@ -0,0 +1,6 @@ +package org.ultramine.mods.bukkit.util; + +public class LightningEffectSwitcher +{ + public static boolean isEffect = false; +} diff --git a/src/main/resources/mixin.umbukkitimpl.json b/src/main/resources/mixin.umbukkitimpl.json index 7bd2671..076e80b 100644 --- a/src/main/resources/mixin.umbukkitimpl.json +++ b/src/main/resources/mixin.umbukkitimpl.json @@ -18,6 +18,7 @@ "block.MixinBlockSnow", "block.MixinBlockMycelium", "block.MixinBlockDynamicLiquid", + "block.MixinBlockStaticLiquid", "block.MixinBlockDragonEgg", "block.MixinBlockCactus", "block.MixinBlockCocoa", @@ -46,9 +47,11 @@ "entity.projectile.MixinEntityPotion", "entity.projectile.MixinEntityLargeFireball", "entity.projectile.MixinEntityArrow", + "entity.projectile.MixinEntitySmallFireball", "entity.item.MixinEntityEnderCrystal", "entity.item.MixinEntityItemFrame", "entity.item.MixinEntityFireworkRocket", + "entity.effect.MixinEntityLightningBolt", "inventory.MixinInventoryLargeChest", "item.MixinItemFlintAndSteel", "management.MixinBanEntry", @@ -75,8 +78,7 @@ "init.MixinBootstrapFireworks", "init.MixinBootstrapFireCharge", "init.MixinBootstrapBoat", - "init.MixinBootstrapLavaBucket", - "init.MixinBootstrapWaterBucket", + "init.MixinBootstrapWaterLavaBucket", "init.MixinBootstrapBucket", "init.MixinBootstrapFlintAndSteel", "init.MixinBootstrapDye",