diff --git a/src/main/java/noppes/npcs/NoppesUtilServer.java b/src/main/java/noppes/npcs/NoppesUtilServer.java index 2141f5d83..278878640 100644 --- a/src/main/java/noppes/npcs/NoppesUtilServer.java +++ b/src/main/java/noppes/npcs/NoppesUtilServer.java @@ -320,7 +320,7 @@ public class NoppesUtilServer { float rotationX1, float rotationX2, float rotationXRate, int rotationXRateStart, float rotationY1, float rotationY2, float rotationYRate, int rotationYRateStart, float rotationZ1, float rotationZ2, float rotationZRate, int rotationZRateStart, - boolean facePlayer, + boolean facePlayer, int width, int height, int offsetX, int offsetY, int animRate, int entityID ){ Server.sendToAll(EnumPacketClient.SCRIPTED_PARTICLE, @@ -332,7 +332,7 @@ public class NoppesUtilServer { rotationX1, rotationX2, rotationXRate, rotationXRateStart, rotationY1, rotationY2, rotationYRate, rotationYRateStart, rotationZ1, rotationZ2, rotationZRate, rotationZRateStart, - facePlayer, + facePlayer, width, height, offsetX, offsetY, animRate, entityID ); } diff --git a/src/main/java/noppes/npcs/client/ImageDownloadAlt.java b/src/main/java/noppes/npcs/client/ImageDownloadAlt.java index f32e81c3b..88338c744 100644 --- a/src/main/java/noppes/npcs/client/ImageDownloadAlt.java +++ b/src/main/java/noppes/npcs/client/ImageDownloadAlt.java @@ -76,6 +76,10 @@ public class ImageDownloadAlt extends SimpleTexture } } + public BufferedImage getBufferedImage(){ + return this.bufferedImage; + } + public void loadTexture(IResourceManager resourceManager) throws IOException { if (this.bufferedImage == null && this.textureLocation != null) diff --git a/src/main/java/noppes/npcs/client/NoppesUtil.java b/src/main/java/noppes/npcs/client/NoppesUtil.java index 035478c4d..3b2d1f27a 100644 --- a/src/main/java/noppes/npcs/client/NoppesUtil.java +++ b/src/main/java/noppes/npcs/client/NoppesUtil.java @@ -115,6 +115,12 @@ public class NoppesUtil { boolean facePlayer = buffer.readBoolean(); + int width = buffer.readInt(); + int height = buffer.readInt(); + int offsetX = buffer.readInt(); + int offsetY = buffer.readInt(); + int animRate = buffer.readInt(); + int entityID = buffer.readInt(); World worldObj = Minecraft.getMinecraft().theWorld; @@ -133,7 +139,8 @@ public class NoppesUtil { rotationX1, rotationX2, rotationXRate, rotationXRateStart, rotationY1, rotationY2, rotationYRate, rotationYRateStart, rotationZ1, rotationZ2, rotationZRate, rotationZRateStart, - maxAge, facePlayer + maxAge, facePlayer, + width, height, offsetX, offsetY, animRate ); for(int i = 0; i < amount; i++){ diff --git a/src/main/java/noppes/npcs/client/fx/EntityCustomFX.java b/src/main/java/noppes/npcs/client/fx/EntityCustomFX.java index 339116806..421c4da14 100644 --- a/src/main/java/noppes/npcs/client/fx/EntityCustomFX.java +++ b/src/main/java/noppes/npcs/client/fx/EntityCustomFX.java @@ -5,7 +5,10 @@ import net.minecraft.client.particle.EntityFX; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.texture.ITextureObject; import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.client.renderer.texture.TextureUtil; +import net.minecraft.client.resources.IResource; import net.minecraft.client.resources.SkinManager; +import net.minecraft.client.resources.data.TextureMetadataSection; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.ResourceLocation; @@ -14,6 +17,11 @@ import noppes.npcs.client.ImageDownloadAlt; import noppes.npcs.client.renderer.ImageBufferDownloadAlt; import org.lwjgl.opengl.GL11; +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.InputStream; + public class EntityCustomFX extends EntityFX { private Entity entity; private final ResourceLocation location; @@ -51,6 +59,19 @@ public class EntityCustomFX extends EntityFX { public boolean facePlayer = true; + private int totalWidth, totalHeight; + public int width, height; + public int offsetX, offsetY; + + private int timeSinceStart; + public int animRate; + public int animPosX; + public int animPosY; + + private ImageDownloadAlt imageDownloadAlt = null; + private boolean isUrl = false; + private boolean gotWidthHeight = false; + public EntityCustomFX(Entity entity, String directory, int HEXColor, double x, double y, double z, double motionX, double motionY, double motionZ, float gravity, float scale1, float scale2, float scaleRate, int scaleRateStart, @@ -58,7 +79,7 @@ public class EntityCustomFX extends EntityFX { float rotationX1, float rotationX2, float rotationXRate, int rotationXRateStart, float rotationY1, float rotationY2, float rotationYRate, int rotationYRateStart, float rotationZ1, float rotationZ2, float rotationZRate, int rotationZRateStart, - int age, boolean facePlayer) { + int age, boolean facePlayer, int width, int height, int offsetX, int offsetY, int animRate) { super(entity.worldObj, x, y, z, motionX, motionY, motionZ); this.scale1 = scale1; @@ -123,19 +144,67 @@ public class EntityCustomFX extends EntityFX { } location = new ResourceLocation(directory); + + this.width = width; + this.height = height; + this.offsetX = offsetX; + this.offsetY = offsetY; + this.animRate = animRate; + if(directory.startsWith("https://")){ + isUrl = true; TextureManager texturemanager = Minecraft.getMinecraft().getTextureManager(); - ITextureObject object = new ImageDownloadAlt(null, directory, new ResourceLocation("customnpcs:textures/gui/invisible.png"), new ImageBufferDownloadAlt(true,false)); - texturemanager.loadTexture(this.location, object); + imageDownloadAlt = new ImageDownloadAlt(null, directory, new ResourceLocation("customnpcs:textures/gui/invisible.png"), new ImageBufferDownloadAlt(true,false)); + texturemanager.loadTexture(this.location, imageDownloadAlt); + } else { + try { + getWidthHeight(); + } catch (IOException e) { + e.printStackTrace(); + } } this.facePlayer = facePlayer; } - @Override + @Override + public void onUpdate() { + ++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 && gotWidthHeight){ + animPosX += width; + if(animPosX + width > totalWidth) { + animPosX = offsetX; + animPosY += height; + if(animPosY > totalHeight) { + animPosY = offsetY; + } + } + } + } + + @Override public void renderParticle(Tessellator tessellator, float partialTick, float cosYaw, float cosPitch, float sinYaw, float sinSinPitch, float cosSinPitch) { tessellator.draw(); + ClientProxy.bindTexture(location); + GL11.glDisable(GL11.GL_BLEND); + + if(imageDownloadAlt != null && isUrl && !gotWidthHeight){ + getURLWidthHeight(); + } if(move){ startX = (float)(entity.prevPosX + (entity.posX - entity.prevPosX) * (double)partialTick); @@ -173,79 +242,87 @@ public class EntityCustomFX extends EntityFX { else if(particleAge >= this.rotationZRateStart) rotationZ += rotationZChange; - float u1 = 0.0f; - float u2 = 1.0f; - float v1 = 0.0f; - float v2 = 1.0f; - - float renderScale = 0.1F * particleScale; - - 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); - - EntityPlayer player = Minecraft.getMinecraft().thePlayer; - double yaw = (player.rotationYaw/180)*Math.PI; - double pitch = (player.rotationPitch/180)*Math.PI; - - GL11.glPushMatrix(); - ClientProxy.bindTexture(location); - GL11.glTranslated((double)posX, (double)posY, (double)posZ); - - if(facePlayer) { - GL11.glRotated(rotationX, Math.cos(yaw) * Math.cos(pitch), 0.0, Math.sin(yaw) * Math.cos(pitch)); - GL11.glRotated(rotationY, -Math.sin(yaw) * Math.sin(pitch), Math.cos(pitch), Math.cos(yaw) * Math.sin(pitch)); - GL11.glRotated(rotationZ, Math.sin(yaw) * Math.cos(pitch), Math.sin(pitch), -Math.cos(yaw) * Math.cos(pitch)); - } else { - GL11.glRotated(player.rotationYaw % 360, 0.0, 1.0, 0.0); - GL11.glRotated(rotationY, 0.0, 1.0, 0.0); - GL11.glRotated(rotationX, Math.cos(yaw), 0.0, Math.sin(yaw)); - GL11.glRotated(rotationZ, Math.sin(yaw), 0.0, -Math.cos(yaw)); - GL11.glRotated((90 - player.rotationPitch), Math.cos(yaw), 0.0, Math.sin(yaw)); - } - - tessellator.startDrawingQuads(); - tessellator.setBrightness(240); - tessellator.setColorOpaque_F(1, 1, 1); - tessellator.setColorRGBA_F(particleRed, particleGreen, particleBlue, particleAlpha); - tessellator.addVertexWithUV( - cosYaw * renderScale - sinSinPitch * renderScale, - cosPitch * renderScale, - sinYaw * renderScale - cosSinPitch * renderScale, u2, v2); - tessellator.addVertexWithUV(( - cosYaw * renderScale) + sinSinPitch * renderScale, + cosPitch * renderScale, ( - sinYaw * renderScale) + cosSinPitch * renderScale, u2, v1); - tessellator.addVertexWithUV( + cosYaw * renderScale + sinSinPitch * renderScale, + cosPitch * renderScale, + sinYaw * renderScale + cosSinPitch * renderScale, u1, v1); - tessellator.addVertexWithUV(( + cosYaw * renderScale) - sinSinPitch * renderScale, - cosPitch * renderScale, ( + sinYaw * renderScale) - cosSinPitch * renderScale, u1, v2); - tessellator.draw(); - GL11.glPopMatrix(); - - GL11.glPushMatrix(); - ClientProxy.bindTexture(location); - GL11.glTranslated((double)posX, (double)posY, (double)posZ); - - if(facePlayer) { - GL11.glRotated(rotationX, Math.cos(yaw) * Math.cos(pitch), 0.0, Math.sin(yaw) * Math.cos(pitch)); - GL11.glRotated(180 + rotationY, -Math.sin(yaw) * Math.sin(pitch), Math.cos(pitch), Math.cos(yaw) * Math.sin(pitch)); - GL11.glRotated(rotationZ, Math.sin(yaw) * Math.cos(pitch), Math.sin(pitch), -Math.cos(yaw) * Math.cos(pitch)); - } else { - GL11.glRotated(player.rotationYaw % 360, 0.0, 1.0, 0.0); - GL11.glRotated(rotationY + 180, 0.0, 1.0, 0.0); - GL11.glRotated(180 - rotationX, Math.cos(yaw), 0.0, Math.sin(yaw)); - GL11.glRotated(rotationZ, Math.sin(yaw), 0.0, -Math.cos(yaw)); - GL11.glRotated((90 - player.rotationPitch), Math.cos(yaw), 0.0, Math.sin(yaw)); - } - - tessellator.startDrawingQuads(); - tessellator.setBrightness(240); - tessellator.setColorOpaque_F(1, 1, 1); - tessellator.setColorRGBA_F(particleRed, particleGreen, particleBlue, particleAlpha); - tessellator.addVertexWithUV( - cosYaw * renderScale - sinSinPitch * renderScale, - cosPitch * renderScale, - sinYaw * renderScale - cosSinPitch * renderScale, u2, v2); - tessellator.addVertexWithUV(( - cosYaw * renderScale) + sinSinPitch * renderScale, + cosPitch * renderScale, ( - sinYaw * renderScale) + cosSinPitch * renderScale, u2, v1); - tessellator.addVertexWithUV( + cosYaw * renderScale + sinSinPitch * renderScale, + cosPitch * renderScale, + sinYaw * renderScale + cosSinPitch * renderScale, u1, v1); - tessellator.addVertexWithUV(( + cosYaw * renderScale) - sinSinPitch * renderScale, - cosPitch * renderScale, ( + sinYaw * renderScale) - cosSinPitch * renderScale, u1, v2); - tessellator.draw(); - GL11.glPopMatrix(); + 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){ + 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 renderScale = 0.1F * particleScale; + 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(); + GL11.glTranslated(posX,posY,posZ); + GL11.glScalef(renderScale, renderScale, renderScale); + 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(); + tessellator.setBrightness(240); + tessellator.setColorOpaque_F(1, 1, 1); + tessellator.setColorRGBA_F(particleRed, particleGreen, particleBlue, particleAlpha); + tessellator.addVertexWithUV( (u2-u1)/2, 0, (v2-v1)/2, u2, v2); + tessellator.addVertexWithUV( (u2-u1)/2, 0, -(v2-v1)/2, u2, v1); + tessellator.addVertexWithUV( -(u2-u1)/2, 0, -(v2-v1)/2, u1, v1); + tessellator.addVertexWithUV( -(u2-u1)/2, 0, (v2-v1)/2, u1, v2); + tessellator.draw(); + GL11.glPopMatrix(); + } + + public void getWidthHeight() throws IOException { + InputStream inputstream = null; + + try { + IResource iresource = Minecraft.getMinecraft().getResourceManager().getResource(location); + inputstream = iresource.getInputStream(); + BufferedImage bufferedimage = ImageIO.read(inputstream); + gotWidthHeight = true; + this.totalWidth = bufferedimage.getWidth(); + this.totalHeight = bufferedimage.getHeight(); + correctWidthHeight(); + } finally { + if (inputstream != null) { + inputstream.close(); + } + } + } + + public void getURLWidthHeight(){ + if(imageDownloadAlt.getBufferedImage() != null) { + gotWidthHeight = true; + this.totalWidth = imageDownloadAlt.getBufferedImage().getWidth(); + this.totalHeight = imageDownloadAlt.getBufferedImage().getHeight(); + correctWidthHeight(); + } + } + + public void correctWidthHeight(){ + totalWidth = Math.max(totalWidth, 1); + totalHeight = Math.max(totalHeight, 1); + this.width = width < 0 ? totalWidth : width; + this.height = height < 0 ? totalHeight : height; + } public int getFXLayer(){ return 0; diff --git a/src/main/java/noppes/npcs/scripted/ScriptEntityParticle.java b/src/main/java/noppes/npcs/scripted/ScriptEntityParticle.java index c81aac693..af51270e4 100644 --- a/src/main/java/noppes/npcs/scripted/ScriptEntityParticle.java +++ b/src/main/java/noppes/npcs/scripted/ScriptEntityParticle.java @@ -33,6 +33,10 @@ public class ScriptEntityParticle { public float rotationZRate = 0.0F; public int rotationZRateStart = 0; + public int width = -1, height = -1; + public int offsetX = 0, offsetY = 0; + public int animRate = 0; + public boolean facePlayer = true; public ScriptEntityParticle(String directory){ @@ -49,11 +53,28 @@ public class ScriptEntityParticle { rotationX1, rotationX2, rotationXRate, rotationXRateStart, rotationY1, rotationY2, rotationYRate, rotationYRateStart, rotationZ1, rotationZ2, rotationZRate, rotationZRateStart, - facePlayer, + facePlayer, width, height, offsetX, offsetY, animRate, entityID ); } + public void setSize(int width, int height){ + this.width = width; + this.height = height; + } + public int getWidth() { return width; } + public int getHeight() { return height; } + + public void setOffset(int offsetX, int offsetY){ + this.offsetX = offsetX; + this.offsetY = offsetY; + } + public int getOffsetX() { return offsetX; } + public int getOffsetY() { return offsetY; } + + public void setAnimRate(int animRate) { this.animRate = animRate; } + public int getAnimRate() { return animRate; } + public boolean getFacePlayer() { return facePlayer; } public void setFacePlayer(boolean facePlayer) { this.facePlayer = facePlayer; } diff --git a/src/main/java/noppes/npcs/scripted/entity/ScriptEntity.java b/src/main/java/noppes/npcs/scripted/entity/ScriptEntity.java index 09bb5b4dc..8a83eb4ac 100644 --- a/src/main/java/noppes/npcs/scripted/entity/ScriptEntity.java +++ b/src/main/java/noppes/npcs/scripted/entity/ScriptEntity.java @@ -82,7 +82,7 @@ public class ScriptEntity implements IEntity { rotationX1, rotationX2, rotationXRate, rotationXRateStart, rotationY1, rotationY2, rotationYRate, rotationYRateStart, rotationZ1, rotationZ2, rotationZRate, rotationZRateStart, - true, + true, -1, -1, 0,0, 0, entityID ); } @@ -101,7 +101,7 @@ public class ScriptEntity implements IEntity { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - true, + true, -1, -1, 0,0,0, entityID ); } @@ -119,7 +119,7 @@ public class ScriptEntity implements IEntity { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - true, + true, -1, -1, 0,0,0, entityID ); } @@ -136,7 +136,7 @@ public class ScriptEntity implements IEntity { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - true, + true, -1, -1, 0,0,0, entityID ); } @@ -152,7 +152,7 @@ public class ScriptEntity implements IEntity { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - true, + true, -1, -1, 0,0,0, entityID ); } @@ -167,7 +167,7 @@ public class ScriptEntity implements IEntity { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - true, + true, -1, -1, 0,0,0, entityID ); }