mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-13 04:17:36 +00:00
389 lines
15 KiB
Java
389 lines
15 KiB
Java
package noppes.npcs.client.fx;
|
|
|
|
import cpw.mods.fml.relauncher.Side;
|
|
import cpw.mods.fml.relauncher.SideOnly;
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.particle.EntityFX;
|
|
import net.minecraft.client.renderer.Tessellator;
|
|
import net.minecraft.client.renderer.texture.TextureManager;
|
|
import net.minecraft.client.resources.IResource;
|
|
import net.minecraft.entity.Entity;
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
import net.minecraft.util.MathHelper;
|
|
import net.minecraft.util.ResourceLocation;
|
|
import net.minecraft.world.World;
|
|
import noppes.npcs.client.ClientCacheHandler;
|
|
import noppes.npcs.client.ClientProxy;
|
|
import noppes.npcs.client.ImageDownloadAlt;
|
|
import noppes.npcs.client.renderer.ImageBufferDownloadAlt;
|
|
import noppes.npcs.client.renderer.ImageData;
|
|
import noppes.npcs.scripted.ScriptParticle;
|
|
import org.lwjgl.opengl.GL11;
|
|
|
|
import javax.imageio.ImageIO;
|
|
import java.awt.image.BufferedImage;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
|
|
public class CustomFX extends EntityFX {
|
|
private final Entity entity;
|
|
private final String directory;
|
|
private final ImageData imageData;
|
|
private static final ResourceLocation resource = new ResourceLocation("textures/particle/particles.png");
|
|
private float startX = 0, startY = 0, startZ = 0;
|
|
|
|
public float scaleX1 = 1.0F;
|
|
public float scaleX2 = 1.0F;
|
|
public float scaleXRate = 1.0F;
|
|
public int scaleXRateStart = 0;
|
|
|
|
public float scaleY1 = 1.0F;
|
|
public float scaleY2 = 1.0F;
|
|
public float scaleYRate = 1.0F;
|
|
public int scaleYRateStart = 0;
|
|
|
|
public float alpha1 = 1.0F;
|
|
public float alpha2 = 0;
|
|
public float alphaRate = 0.0F;
|
|
public int alphaRateStart = 0;
|
|
|
|
public float rotationX = 0;
|
|
public float rotationX1 = 0;
|
|
public float rotationX2 = 0;
|
|
public float rotationXRate = 0.0F;
|
|
public int rotationXRateStart = 0;
|
|
|
|
public float rotationY = 0;
|
|
public float rotationY1 = 0;
|
|
public float rotationY2 = 0;
|
|
public float rotationYRate = 0.0F;
|
|
public int rotationYRateStart = 0;
|
|
|
|
public float rotationZ = 0;
|
|
public float rotationZ1 = 0;
|
|
public float rotationZ2 = 0;
|
|
public float rotationZRate = 0.0F;
|
|
public int rotationZRateStart = 0;
|
|
|
|
public boolean facePlayer = true;
|
|
public boolean glows = true;
|
|
|
|
public int width, height;
|
|
public int offsetX, offsetY;
|
|
|
|
private int timeSinceStart;
|
|
public int animRate;
|
|
public boolean animLoop;
|
|
public int animStart,animEnd;
|
|
private int animPosX;
|
|
private int animPosY;
|
|
|
|
public int HEXColor = 0xFFFFFF;
|
|
public int HEXColor2 = 0xFFFFFF;
|
|
public float HEXColorRate = 0.0F;
|
|
public int HEXColorStart = 0;
|
|
|
|
double renderPosX, renderPosY, renderPosZ;
|
|
|
|
public CustomFX(World worldObj, Entity entity, String directory, double x, double y, double z, double motionX, double motionY, double motionZ) {
|
|
super(worldObj, x, y, z, motionX, motionY, motionZ);
|
|
this.entity = entity;
|
|
this.directory = directory;
|
|
this.imageData = ClientCacheHandler.getImageData(this.directory);
|
|
}
|
|
|
|
public static CustomFX fromScriptedParticle(ScriptParticle particle, World worldObj, Entity entity) {
|
|
CustomFX customFX = new CustomFX(worldObj, entity, particle.directory, particle.x, particle.y, particle.z, particle.motionX, particle.motionY, particle.motionZ);
|
|
|
|
customFX.HEXColor = particle.HEXColor;
|
|
customFX.HEXColor2 = particle.HEXColor2;
|
|
customFX.HEXColorRate = particle.HEXColorRate;
|
|
customFX.HEXColorStart = particle.HEXColorStart;
|
|
customFX.particleRed = (customFX.HEXColor >> 16 & 255) / 255f;
|
|
customFX.particleGreen = (customFX.HEXColor >> 8 & 255) / 255f;
|
|
customFX.particleBlue = (customFX.HEXColor & 255) / 255f;
|
|
|
|
customFX.scaleX1 = particle.scaleX1;
|
|
customFX.scaleX2 = particle.scaleX2;
|
|
customFX.scaleXRate = Math.abs(particle.scaleXRate);
|
|
customFX.scaleXRateStart = particle.scaleXRateStart;
|
|
if(customFX.scaleX1 > customFX.scaleX2)
|
|
customFX.scaleXRate *= -1;
|
|
|
|
customFX.scaleY1 = particle.scaleY1;
|
|
customFX.scaleY2 = particle.scaleY2;
|
|
customFX.scaleYRate = Math.abs(particle.scaleYRate);
|
|
customFX.scaleYRateStart = particle.scaleYRateStart;
|
|
if(customFX.scaleY1 > customFX.scaleY2)
|
|
customFX.scaleYRate *= -1;
|
|
|
|
customFX.alpha1 = particle.alpha1;
|
|
customFX.alpha2 = particle.alpha2;
|
|
customFX.alphaRate = Math.abs(particle.alphaRate);
|
|
customFX.alphaRateStart = particle.alphaRateStart;
|
|
customFX.particleAlpha = customFX.alpha1;
|
|
if(customFX.alpha1 > customFX.alpha2)
|
|
customFX.alphaRate *= -1;
|
|
|
|
customFX.rotationX1 = particle.rotationX1;
|
|
customFX.rotationX2 = particle.rotationX2;
|
|
customFX.rotationXRate = Math.abs(particle.rotationXRate);
|
|
customFX.rotationXRateStart = particle.rotationXRateStart;
|
|
customFX.rotationX = customFX.rotationX1;
|
|
if(customFX.rotationX1 > customFX.rotationX2)
|
|
customFX.rotationXRate *= -1;
|
|
|
|
customFX.rotationY1 = particle.rotationY1;
|
|
customFX.rotationY2 = particle.rotationY2;
|
|
customFX.rotationYRate = Math.abs(particle.rotationYRate);
|
|
customFX.rotationYRateStart = particle.rotationYRateStart;
|
|
customFX.rotationY = customFX.rotationY1;
|
|
if(customFX.rotationY1 > customFX.rotationY2)
|
|
customFX.rotationYRate *= -1;
|
|
|
|
customFX.rotationZ1 = particle.rotationZ1;
|
|
customFX.rotationZ2 = particle.rotationZ2;
|
|
customFX.rotationZRate = Math.abs(particle.rotationZRate);
|
|
customFX.rotationZRateStart = particle.rotationZRateStart;
|
|
customFX.rotationZ = customFX.rotationZ1;
|
|
if(customFX.rotationZ1 > customFX.rotationZ2)
|
|
customFX.rotationZRate *= -1;
|
|
|
|
customFX.particleGravity = particle.gravity/0.04F;
|
|
customFX.particleMaxAge = particle.maxAge;
|
|
|
|
customFX.motionX = particle.motionX;
|
|
customFX.motionY = particle.motionY;
|
|
customFX.motionZ = particle.motionZ;
|
|
|
|
customFX.noClip = particle.noClip;
|
|
|
|
customFX.width = particle.width;
|
|
customFX.height = particle.height;
|
|
customFX.offsetX = particle.offsetX;
|
|
customFX.offsetY = particle.offsetY;
|
|
|
|
customFX.animRate = particle.animRate;
|
|
customFX.animLoop = particle.animLoop;
|
|
customFX.animStart = particle.animStart;
|
|
customFX.animEnd = particle.animEnd;
|
|
if(customFX.animEnd < customFX.animStart)
|
|
customFX.animEnd = customFX.animStart + customFX.particleMaxAge;
|
|
|
|
customFX.facePlayer = particle.facePlayer;
|
|
customFX.glows = particle.glows;
|
|
|
|
return customFX;
|
|
}
|
|
|
|
@Override
|
|
public void onUpdate() {
|
|
if (!this.imageLoaded()) {
|
|
return;
|
|
}
|
|
|
|
++this.timeSinceStart;
|
|
|
|
if (this.timeSinceStart == this.particleMaxAge)
|
|
{
|
|
this.setDead();
|
|
}
|
|
|
|
this.prevPosX = this.posX;
|
|
this.prevPosY = this.posY;
|
|
this.prevPosZ = this.posZ;
|
|
|
|
this.motionY -= 0.04D * (double)this.particleGravity;
|
|
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
|
|
|
if (animRate > 0 && timeSinceStart % animRate == 0 && timeSinceStart > 0 && timeSinceStart >= animStart && timeSinceStart <= animEnd && (animLoop || animPosY <= imageData.getTotalHeight())) {
|
|
animPosX += width;
|
|
if (animPosX + width > imageData.getTotalWidth()) {
|
|
animPosX = offsetX;
|
|
animPosY += height;
|
|
if (animPosY > imageData.getTotalHeight() && animLoop) {
|
|
animPosY = offsetY;
|
|
}
|
|
}
|
|
}
|
|
|
|
particleRed = (HEXColor >> 16 & 255) / 255f;
|
|
particleGreen = (HEXColor >> 8 & 255) / 255f;
|
|
particleBlue = (HEXColor & 255) / 255f;
|
|
|
|
if(timeSinceStart >= HEXColorStart)
|
|
HEXColor = lerpColor(HEXColor, HEXColor2, HEXColorRate);
|
|
}
|
|
|
|
@Override
|
|
public void renderParticle(Tessellator tessellator, float partialTick, float cosYaw, float cosPitch, float sinYaw, float sinSinPitch, float cosSinPitch)
|
|
{
|
|
if (!this.imageLoaded()) {
|
|
return;
|
|
}
|
|
|
|
tessellator.draw();
|
|
imageData.bindTexture();
|
|
if (imageData.invalid()) {
|
|
setDead();
|
|
}
|
|
|
|
if(entity != null){
|
|
startX = (float)(entity.prevPosX + (entity.posX - entity.prevPosX) * (double)partialTick);
|
|
startY = (float)(entity.prevPosY + (entity.posY - entity.prevPosY) * (double)partialTick);
|
|
startZ = (float)(entity.prevPosZ + (entity.posZ - entity.prevPosZ) * (double)partialTick);
|
|
}
|
|
|
|
float scaleXChange = this.scaleXRate / (float)particleMaxAge;
|
|
if((this.scaleXRate < 0 && this.scaleX1+scaleXChange < this.scaleX2) || (this.scaleXRate > 0 && this.scaleX1+scaleXChange > this.scaleX2))
|
|
this.scaleX1 = this.scaleX2;
|
|
else if(timeSinceStart >= this.scaleXRateStart)
|
|
this.scaleX1 += scaleXChange;
|
|
|
|
float scaleYChange = this.scaleYRate / (float)particleMaxAge;
|
|
if((this.scaleYRate < 0 && this.scaleY1+scaleYChange < this.scaleY2) || (this.scaleYRate > 0 && this.scaleY1+scaleYChange > this.scaleY2))
|
|
this.scaleY1 = this.scaleY2;
|
|
else if(timeSinceStart >= this.scaleYRateStart)
|
|
this.scaleY1 += scaleYChange;
|
|
|
|
float alphaChange = this.alphaRate / (float)particleMaxAge;
|
|
if((this.alphaRate < 0 && particleAlpha+alphaChange < this.alpha2) || (this.alphaRate > 0 && particleAlpha+alphaChange > this.alpha2))
|
|
particleAlpha = this.alpha2;
|
|
else if(timeSinceStart >= this.alphaRateStart)
|
|
particleAlpha += alphaChange;
|
|
|
|
float rotationXChange = this.rotationXRate / (float)particleMaxAge;
|
|
if((this.rotationXRate < 0 && rotationX+rotationXChange < this.rotationX2) || (this.rotationXRate > 0 && rotationX+rotationXChange > this.rotationX2))
|
|
rotationX = this.rotationX2;
|
|
else if(timeSinceStart >= this.rotationXRateStart)
|
|
rotationX += rotationXChange;
|
|
|
|
float rotationYChange = this.rotationYRate / (float)particleMaxAge;
|
|
if((this.rotationYRate < 0 && rotationY+rotationYChange < this.rotationY2) || (this.rotationYRate > 0 && rotationY+rotationYChange > this.rotationY2))
|
|
rotationY = this.rotationY2;
|
|
else if(timeSinceStart >= this.rotationYRateStart)
|
|
rotationY += rotationYChange;
|
|
|
|
float rotationZChange = this.rotationZRate / (float)particleMaxAge;
|
|
if((this.rotationZRate < 0 && rotationZ+rotationZChange < this.rotationZ2) || (this.rotationZRate > 0 && rotationZ+rotationZChange > this.rotationZ2))
|
|
rotationZ = this.rotationZ2;
|
|
else if(timeSinceStart >= this.rotationZRateStart)
|
|
rotationZ += rotationZChange;
|
|
|
|
renderParticleSide(true, tessellator, partialTick);
|
|
renderParticleSide(false, tessellator, partialTick);
|
|
|
|
GL11.glColor4f(1, 1, 1, 1.0F);
|
|
ClientProxy.bindTexture(resource);
|
|
tessellator.startDrawingQuads();
|
|
}
|
|
|
|
public void renderParticleSide(boolean front, Tessellator tessellator, float partialTick){
|
|
int totalWidth = imageData.getTotalWidth();
|
|
int totalHeight = imageData.getTotalHeight();
|
|
|
|
float u1 = (float)offsetX/(float)totalWidth + (float)animPosX/(float)totalWidth;
|
|
float u2 = u1 + (float)width/(float)totalWidth;
|
|
float v1 = (float)offsetY/(float)totalHeight + (float)animPosY/(float)totalHeight;
|
|
float v2 = v1 + (float)height/(float)totalHeight;
|
|
|
|
EntityPlayer player = Minecraft.getMinecraft().thePlayer;
|
|
float posX = (float)((prevPosX + (this.posX - prevPosX) * (double)partialTick) - interpPosX) + startX;
|
|
float posY = (float)((prevPosY + (this.posY - prevPosY) * (double)partialTick) - interpPosY) + startY;
|
|
float posZ = (float)((prevPosZ + (this.posZ - prevPosZ) * (double)partialTick) - interpPosZ) + startZ;
|
|
|
|
GL11.glPushMatrix();
|
|
renderPosX = startX + posX + this.posX;
|
|
renderPosY = startY + posY + this.posY;
|
|
renderPosZ = startZ + posZ + this.posZ;
|
|
|
|
GL11.glTranslated(posX,posY,posZ);
|
|
if(facePlayer) {
|
|
GL11.glRotated(180 - player.rotationYaw, 0.0, 1.0, 0.0);
|
|
GL11.glRotated(-player.rotationPitch + 90, 1.0, 0.0, 0.0);
|
|
|
|
GL11.glRotated(rotationX, 1.0, 0.0, 0.0);
|
|
GL11.glRotated(rotationZ, 0.0, 1.0, 0.0);
|
|
GL11.glRotated(rotationY + (!front ? 180 : 0), 0.0, 0.0, 1.0);
|
|
} else {
|
|
GL11.glRotated(rotationX, 1.0, 0.0, 0.0);
|
|
GL11.glRotated(rotationY, 0.0, 1.0, 0.0);
|
|
GL11.glRotated(rotationZ + (!front ? 180 : 0), 0.0, 0.0, 1.0);
|
|
}
|
|
|
|
tessellator.startDrawingQuads();
|
|
if (!this.glows) {
|
|
tessellator.setBrightness(this.getBrightnessForRender(partialTick));
|
|
} else {
|
|
tessellator.setBrightness(240);
|
|
}
|
|
|
|
float textureXScale = 1.0F, textureYScale = 1.0F;
|
|
if (totalWidth > totalHeight) {
|
|
textureYScale = (float) totalHeight/totalWidth;
|
|
GL11.glScalef(1/textureYScale/2,1/textureYScale/2,1/textureYScale/2);
|
|
} else if(totalHeight > totalWidth) {
|
|
textureXScale = (float) totalWidth/totalHeight;
|
|
GL11.glScalef(1/textureXScale/2,1/textureXScale/2,1/textureXScale/2);
|
|
}
|
|
textureXScale *= scaleX1/10.0F;
|
|
textureYScale *= scaleY1/10.0F;
|
|
|
|
tessellator.setColorOpaque_F(1, 1, 1);
|
|
tessellator.setColorRGBA_F(particleRed, particleGreen, particleBlue, particleAlpha);
|
|
tessellator.addVertexWithUV( textureXScale * (u2-u1)/2, 0, textureYScale * (v2-v1)/2, u2, v2);
|
|
tessellator.addVertexWithUV( textureXScale * (u2-u1)/2, 0, textureYScale * -(v2-v1)/2, u2, v1);
|
|
tessellator.addVertexWithUV( textureXScale * -(u2-u1)/2, 0, textureYScale * -(v2-v1)/2, u1, v1);
|
|
tessellator.addVertexWithUV( textureXScale * -(u2-u1)/2, 0, textureYScale * (v2-v1)/2, u1, v2);
|
|
tessellator.draw();
|
|
GL11.glPopMatrix();
|
|
}
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
public int getBrightnessForRender(float p_70070_1_)
|
|
{
|
|
int i = MathHelper.floor_double(renderPosX);
|
|
int j = MathHelper.floor_double(renderPosZ);
|
|
|
|
if (this.worldObj.blockExists(i, 0, j))
|
|
{
|
|
double d0 = (this.boundingBox.maxY - this.boundingBox.minY) * 0.66D;
|
|
int k = MathHelper.floor_double(renderPosY - (double)this.yOffset + d0);
|
|
return this.worldObj.getLightBrightnessForSkyBlocks(i, k, j, 0);
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
public int lerpColor(int from, int to, float ratio) {
|
|
float ar = (from & 0xFF0000) >> 16;
|
|
float ag = (from & 0x00FF00) >> 8;
|
|
float ab = (from & 0x0000FF);
|
|
|
|
float br = (to & 0xFF0000) >> 16;
|
|
float bg = (to & 0x00FF00) >> 8;
|
|
float bb = (to & 0x0000FF);
|
|
|
|
float rr = ar + ratio * (br - ar);
|
|
float rg = ag + ratio * (bg - ag);
|
|
float rb = ab + ratio * (bb - ab);
|
|
|
|
return (int)(((int)rr << 16) + ((int)rg << 8) + (rb));
|
|
}
|
|
|
|
public int getFXLayer(){
|
|
return 0;
|
|
}
|
|
|
|
public boolean imageLoaded() {
|
|
if (imageData.imageLoaded()) {
|
|
this.width = width < 0 ? imageData.getTotalWidth() : width;
|
|
this.height = height < 0 ? imageData.getTotalHeight() : height;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|