diff --git a/src/main/java/forestry/core/render/ParticleHelper.java b/src/main/java/forestry/core/render/ParticleHelper.java new file mode 100644 index 000000000..6b716209e --- /dev/null +++ b/src/main/java/forestry/core/render/ParticleHelper.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.core.render; + +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.client.particle.EffectRenderer; +import net.minecraft.client.particle.EntityDiggingFX; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +/** + * @author CovertJaguar + */ +public class ParticleHelper { + + private static final Random rand = new Random(); + + @SideOnly(Side.CLIENT) + public static boolean addHitEffects(World world, Block block, MovingObjectPosition target, EffectRenderer effectRenderer, ParticleHelperCallback callback) { + int x = target.blockX; + int y = target.blockY; + int z = target.blockZ; + + int sideHit = target.sideHit; + + if (block != world.getBlock(x, y, z)) + return true; + + int meta = world.getBlockMetadata(x, y, z); + + float b = 0.1F; + double px = x + rand.nextDouble() * (block.getBlockBoundsMaxX() - block.getBlockBoundsMinX() - (b * 2.0F)) + b + block.getBlockBoundsMinX(); + double py = y + rand.nextDouble() * (block.getBlockBoundsMaxY() - block.getBlockBoundsMinY() - (b * 2.0F)) + b + block.getBlockBoundsMinY(); + double pz = z + rand.nextDouble() * (block.getBlockBoundsMaxZ() - block.getBlockBoundsMinZ() - (b * 2.0F)) + b + block.getBlockBoundsMinZ(); + + if (sideHit == 0) + py = (double) y + block.getBlockBoundsMinY() - (double) b; + + if (sideHit == 1) + py = (double) y + block.getBlockBoundsMaxY() + (double) b; + + if (sideHit == 2) + pz = (double) z + block.getBlockBoundsMinZ() - (double) b; + + if (sideHit == 3) + pz = (double) z + block.getBlockBoundsMaxZ() + (double) b; + + if (sideHit == 4) + px = (double) x + block.getBlockBoundsMinX() - (double) b; + + if (sideHit == 5) + px = (double) x + block.getBlockBoundsMaxX() + (double) b; + + EntityDiggingFX fx = new EntityDiggingFX(world, px, py, pz, 0.0D, 0.0D, 0.0D, block, sideHit, meta); + fx.setParticleIcon(block.getIcon(world, x, y, z, 0)); + + if (callback != null) + callback.addHitEffects(fx, world, x, y, z, meta); + + effectRenderer.addEffect(fx.applyColourMultiplier(x, y, z).multiplyVelocity(0.2F).multipleParticleScaleBy(0.6F)); + + return true; + } + + /** + * Spawn particles for when the block is destroyed. Due to the nature of how + * this is invoked, the x/y/z locations are not always guaranteed to host + * your block. So be sure to do proper sanity checks before assuming that + * the location is this block. + * + * @param world The current world + * @param block + * @param x X position to spawn the particle + * @param y Y position to spawn the particle + * @param z Z position to spawn the particle + * @param meta The metadata for the block before it was destroyed. + * @param effectRenderer A reference to the current effect renderer. + * @param callback + * @return True to prevent vanilla break particles from spawning. + */ + @SideOnly(Side.CLIENT) + public static boolean addDestroyEffects(World world, Block block, int x, int y, int z, int meta, EffectRenderer effectRenderer, ParticleHelperCallback callback) { + if (block != world.getBlock(x, y, z)) + return true; + + byte iterations = 4; + for (int i = 0; i < iterations; ++i) { + for (int j = 0; j < iterations; ++j) { + for (int k = 0; k < iterations; ++k) { + double px = x + (i + 0.5D) / (double) iterations; + double py = y + (j + 0.5D) / (double) iterations; + double pz = z + (k + 0.5D) / (double) iterations; + int random = rand.nextInt(6); + + EntityDiggingFX fx = new EntityDiggingFX(world, px, py, pz, px - x - 0.5D, py - y - 0.5D, pz - z - 0.5D, block, random, meta); + fx.setParticleIcon(block.getIcon(world, x, y, z, 0)); + + if (callback != null) + callback.addDestroyEffects(fx, world, x, y, z, meta); + + effectRenderer.addEffect(fx.applyColourMultiplier(x, y, z)); + } + } + } + + return true; + } + +} diff --git a/src/main/java/forestry/core/render/ParticleHelperCallback.java b/src/main/java/forestry/core/render/ParticleHelperCallback.java new file mode 100644 index 000000000..73a921eac --- /dev/null +++ b/src/main/java/forestry/core/render/ParticleHelperCallback.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2011-2014 SirSengir. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser Public License v3 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl-3.0.txt + * + * Various Contributors including, but not limited to: + * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges + ******************************************************************************/ +package forestry.core.render; + +import net.minecraft.client.particle.EntityDiggingFX; +import net.minecraft.world.World; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +/** + * @author CovertJaguar + */ +public interface ParticleHelperCallback { + + @SideOnly(Side.CLIENT) + void addHitEffects(EntityDiggingFX fx, World world, int x, int y, int z, int meta); + + @SideOnly(Side.CLIENT) + void addDestroyEffects(EntityDiggingFX fx, World world, int x, int y, int z, int meta); +} diff --git a/src/main/java/forestry/farming/gadgets/BlockFarm.java b/src/main/java/forestry/farming/gadgets/BlockFarm.java index 270f55bd1..bcc850fa9 100755 --- a/src/main/java/forestry/farming/gadgets/BlockFarm.java +++ b/src/main/java/forestry/farming/gadgets/BlockFarm.java @@ -14,6 +14,8 @@ import java.util.ArrayList; import java.util.List; import net.minecraft.block.material.Material; +import net.minecraft.client.particle.EffectRenderer; +import net.minecraft.client.particle.EntityDiggingFX; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.EntityLivingBase; @@ -32,14 +34,19 @@ import cpw.mods.fml.relauncher.SideOnly; import forestry.core.gadgets.BlockStructure; import forestry.core.proxy.Proxies; +import forestry.core.render.ParticleHelper; +import forestry.core.render.ParticleHelperCallback; import forestry.core.utils.StackUtils; import forestry.plugins.PluginFarming; public class BlockFarm extends BlockStructure { + private static BlockFarm instance; + public BlockFarm() { super(Material.rock); setHardness(1.0f); + instance = this; } @Override @@ -146,6 +153,41 @@ public class BlockFarm extends BlockStructure { EnumFarmBlock.registerIcons(register); } + + private static class ParticleCallback implements ParticleHelperCallback { + + @Override + @SideOnly(Side.CLIENT) + public void addHitEffects(EntityDiggingFX fx, World world, int x, int y, int z, int meta) { + setTexture(fx, world, x, y, z, meta); + } + + @Override + @SideOnly(Side.CLIENT) + public void addDestroyEffects(EntityDiggingFX fx, World world, int x, int y, int z, int meta) { + setTexture(fx, world, x, y, z, meta); + } + + @SideOnly(Side.CLIENT) + private void setTexture(EntityDiggingFX fx, World world, int x, int y, int z, int meta) { + fx.setParticleIcon(instance.getIcon(world, x, y, z, 0)); + } + + } + private static final ParticleHelperCallback callback = new ParticleCallback(); + + @SideOnly(Side.CLIENT) + @Override + public boolean addHitEffects(World worldObj, MovingObjectPosition target, EffectRenderer effectRenderer) { + return ParticleHelper.addHitEffects(worldObj, instance, target, effectRenderer, callback); + } + + @SideOnly(Side.CLIENT) + @Override + public boolean addDestroyEffects(World worldObj, int x, int y, int z, int meta, EffectRenderer effectRenderer) { + return ParticleHelper.addDestroyEffects(worldObj, instance, x, y, z, meta, effectRenderer, callback); + } + @SideOnly(Side.CLIENT) @Override public IIcon getIcon(int side, int metadata) {