// Path: src/api/java/com/github/atomicblom/shearmadness/api/capability/IChiseledSheepCapability.java
// public interface IChiseledSheepCapability
// {
//     boolean isChiseled();
// 
//     void unChisel();
// 
//     void chisel(ItemStack itemStack);
// 
//     ItemStack getChiselItemStack();
// 
//     int getItemIdentifier();
// 
//     NBTTagCompound getExtraData();
// }
// 
// Path: src/api/java/com/github/atomicblom/shearmadness/api/particles/CustomParticleFactoryBase.java
// public abstract class CustomParticleFactoryBase implements ICustomParticleFactory {
//     private ResourceLocation registryName;
// 
//     @SideOnly(Side.CLIENT)
//     private IParticleFactory factory;
// 
//     @Override
//     @SideOnly(Side.CLIENT)
//     public IParticleFactory getParticleFactory() {
//         if (factory == null) {
//             factory = (particleID, worldIn, xCoordIn, yCoordIn, zCoordIn, xSpeedIn, ySpeedIn, zSpeedIn, parameters) -> createCustomParticle(worldIn, xCoordIn, yCoordIn, zCoordIn, xSpeedIn, ySpeedIn, zSpeedIn, parameters);
//         }
//         return factory;
//     }
// 
//     @SideOnly(Side.CLIENT)
//     protected abstract Particle createCustomParticle(World worldIn, double xCoordIn, double yCoordIn, double zCoordIn, double xSpeedIn, double ySpeedIn, double zSpeedIn, int... p_178902_15_);
// 
//     @Override
//     public ICustomParticleFactory setRegistryName(ResourceLocation name) {
//         registryName = name;
//         return this;
//     }
// 
//     @Override
//     public ResourceLocation getRegistryName() {
//         return registryName;
//     }
// 
//     @Override
//     public Class<? super ICustomParticleFactory> getRegistryType() {
//         return ICustomParticleFactory.class;
//     }
// }
// 
// Path: src/api/java/com/github/atomicblom/shearmadness/api/particles/ICustomParticleFactory.java
// public interface ICustomParticleFactory extends IForgeRegistryEntry<ICustomParticleFactory> {
//     @SideOnly(Side.CLIENT)
//     IParticleFactory getParticleFactory();
// }
// 
// Path: src/integration/java/com/github/atomicblom/shearmadness/variations/chancecubes/ChanceCubesLibrary.java
// @ObjectHolder(ChanceCubesReference.CHANCE_CUBES_MODID)
// public class ChanceCubesLibrary
// {
//     @ObjectHolder("chance_Cube")
//     public static final Block chance_cube;
// 
//     @ObjectHolder("chance_Icosahedron")
//     public static final Block chance_icosadedron;
// 
//     @ObjectHolder("compact_Giant_Chance_Cube")
//     public static final Block chance_cube_giant_compact;
// 
//     @ObjectHolder("giant_Chance_Cube")
//     public static final Block chance_cube_giant;
// 
//     static {
//         chance_cube = null;
//         chance_icosadedron = null;
//         chance_cube_giant = null;
//         chance_cube_giant_compact = null;
//     }
// }
// 
// Path: src/api/java/com/github/atomicblom/shearmadness/api/Capability.java
// @CapabilityInject(IChiseledSheepCapability.class)
// public static final net.minecraftforge.common.capabilities.Capability<IChiseledSheepCapability> CHISELED_SHEEP;


import com.github.atomicblom.shearmadness.api.capability.IChiseledSheepCapability;
import com.github.atomicblom.shearmadness.api.particles.CustomParticleFactoryBase;
import com.github.atomicblom.shearmadness.api.particles.ICustomParticleFactory;
import com.github.atomicblom.shearmadness.variations.chancecubes.ChanceCubesLibrary;
import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.IParticleFactory;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.monster.EntityGuardian;
import net.minecraft.entity.passive.EntitySheep;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import static com.github.atomicblom.shearmadness.api.Capability.CHISELED_SHEEP;

            float particleAge = ((float)this.particleAge + partialTicks) / (float)this.particleMaxAge;
            GlStateManager.depthMask(true);
            GlStateManager.enableBlend();
            GlStateManager.enableDepth();
            GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
            float lightLevel = 240.0F;
            OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, lightLevel, lightLevel);
            GlStateManager.pushMatrix();
            float alpha = 0.05F + 0.5F * MathHelper.sin(particleAge * (float)Math.PI);
            GlStateManager.color(1.0F, 1.0F, 1.0F, alpha);
            GlStateManager.translate(0.0F, 1.8F, 0.0F);
            GlStateManager.rotate(180.0F - entityIn.rotationYaw, 0.0F, 1.0F, 0.0F);
            float speed = 150.0F;
            GlStateManager.rotate(260 - (60.0F - speed * particleAge - entityIn.rotationPitch), 1.0F, 0.0F, 0.0F);
            float scale = 1.2F;
            GlStateManager.translate(0.0F, -0.4F, -2.2);
            GlStateManager.rotate(30.0f, 1.0F, 0.0F, 0.0F);
            GlStateManager.scale(scale, scale, scale);

            this.entity.rotationYaw = 0.0F;
            this.entity.rotationYawHead = 0.0F;
            this.entity.prevRotationYaw = 0.0F;
            this.entity.prevRotationYawHead = 0.0F;
            rendermanager.doRenderEntity(this.entity, 0.0D, 0.0D, 0.0D, 0.0F, partialTicks, false);
            GlStateManager.popMatrix();
            GlStateManager.enableDepth();
        }
    }

// Path: src/api/java/com/github/atomicblom/shearmadness/api/capability/IChiseledSheepCapability.java
// public interface IChiseledSheepCapability
// {
//     boolean isChiseled();
// 
//     void unChisel();
// 
//     void chisel(ItemStack itemStack);
// 
//     ItemStack getChiselItemStack();
// 
//     int getItemIdentifier();
// 
//     NBTTagCompound getExtraData();
// }
// 
// Path: src/api/java/com/github/atomicblom/shearmadness/api/particles/CustomParticleFactoryBase.java
// public abstract class CustomParticleFactoryBase implements ICustomParticleFactory {
//     private ResourceLocation registryName;
// 
//     @SideOnly(Side.CLIENT)
//     private IParticleFactory factory;
// 
//     @Override
//     @SideOnly(Side.CLIENT)
//     public IParticleFactory getParticleFactory() {
//         if (factory == null) {
//             factory = (particleID, worldIn, xCoordIn, yCoordIn, zCoordIn, xSpeedIn, ySpeedIn, zSpeedIn, parameters) -> createCustomParticle(worldIn, xCoordIn, yCoordIn, zCoordIn, xSpeedIn, ySpeedIn, zSpeedIn, parameters);
//         }
//         return factory;
//     }
// 
//     @SideOnly(Side.CLIENT)
//     protected abstract Particle createCustomParticle(World worldIn, double xCoordIn, double yCoordIn, double zCoordIn, double xSpeedIn, double ySpeedIn, double zSpeedIn, int... p_178902_15_);
// 
//     @Override
//     public ICustomParticleFactory setRegistryName(ResourceLocation name) {
//         registryName = name;
//         return this;
//     }
// 
//     @Override
//     public ResourceLocation getRegistryName() {
//         return registryName;
//     }
// 
//     @Override
//     public Class<? super ICustomParticleFactory> getRegistryType() {
//         return ICustomParticleFactory.class;
//     }
// }
// 
// Path: src/api/java/com/github/atomicblom/shearmadness/api/particles/ICustomParticleFactory.java
// public interface ICustomParticleFactory extends IForgeRegistryEntry<ICustomParticleFactory> {
//     @SideOnly(Side.CLIENT)
//     IParticleFactory getParticleFactory();
// }
// 
// Path: src/integration/java/com/github/atomicblom/shearmadness/variations/chancecubes/ChanceCubesLibrary.java
// @ObjectHolder(ChanceCubesReference.CHANCE_CUBES_MODID)
// public class ChanceCubesLibrary
// {
//     @ObjectHolder("chance_Cube")
//     public static final Block chance_cube;
// 
//     @ObjectHolder("chance_Icosahedron")
//     public static final Block chance_icosadedron;
// 
//     @ObjectHolder("compact_Giant_Chance_Cube")
//     public static final Block chance_cube_giant_compact;
// 
//     @ObjectHolder("giant_Chance_Cube")
//     public static final Block chance_cube_giant;
// 
//     static {
//         chance_cube = null;
//         chance_icosadedron = null;
//         chance_cube_giant = null;
//         chance_cube_giant_compact = null;
//     }
// }
// 
// Path: src/api/java/com/github/atomicblom/shearmadness/api/Capability.java
// @CapabilityInject(IChiseledSheepCapability.class)
// public static final net.minecraftforge.common.capabilities.Capability<IChiseledSheepCapability> CHISELED_SHEEP;


// Path: src/integration/java/com/github/atomicblom/shearmadness/variations/chancecubes/client/SheepHeadParticle.java
import com.github.atomicblom.shearmadness.api.capability.IChiseledSheepCapability;
import com.github.atomicblom.shearmadness.api.particles.CustomParticleFactoryBase;
import com.github.atomicblom.shearmadness.api.particles.ICustomParticleFactory;
import com.github.atomicblom.shearmadness.variations.chancecubes.ChanceCubesLibrary;
import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.IParticleFactory;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.monster.EntityGuardian;
import net.minecraft.entity.passive.EntitySheep;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import static com.github.atomicblom.shearmadness.api.Capability.CHISELED_SHEEP;


            float particleAge = ((float)this.particleAge + partialTicks) / (float)this.particleMaxAge;
            GlStateManager.depthMask(true);
            GlStateManager.enableBlend();
            GlStateManager.enableDepth();
            GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
            float lightLevel = 240.0F;
            OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, lightLevel, lightLevel);
            GlStateManager.pushMatrix();
            float alpha = 0.05F + 0.5F * MathHelper.sin(particleAge * (float)Math.PI);
            GlStateManager.color(1.0F, 1.0F, 1.0F, alpha);
            GlStateManager.translate(0.0F, 1.8F, 0.0F);
            GlStateManager.rotate(180.0F - entityIn.rotationYaw, 0.0F, 1.0F, 0.0F);
            float speed = 150.0F;
            GlStateManager.rotate(260 - (60.0F - speed * particleAge - entityIn.rotationPitch), 1.0F, 0.0F, 0.0F);
            float scale = 1.2F;
            GlStateManager.translate(0.0F, -0.4F, -2.2);
            GlStateManager.rotate(30.0f, 1.0F, 0.0F, 0.0F);
            GlStateManager.scale(scale, scale, scale);

            this.entity.rotationYaw = 0.0F;
            this.entity.rotationYawHead = 0.0F;
            this.entity.prevRotationYaw = 0.0F;
            this.entity.prevRotationYawHead = 0.0F;
            rendermanager.doRenderEntity(this.entity, 0.0D, 0.0D, 0.0D, 0.0F, partialTicks, false);
            GlStateManager.popMatrix();
            GlStateManager.enableDepth();
        }
    }

    public static class Factory extends CustomParticleFactoryBase