Reorganise and clean up client event handlers

This commit is contained in:
Electroblob77
2020-06-06 23:25:56 +01:00
parent 6df0d2dc6e
commit 1a094e1970
50 changed files with 625 additions and 443 deletions
@@ -0,0 +1,169 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.renderer.RayHelper;
import electroblob.wizardry.entity.construct.EntityBlackHole;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import org.lwjgl.opengl.GL11;
import java.util.ArrayList;
import java.util.Collections;
public class RenderBlackHole extends Render<EntityBlackHole> {
private static final ResourceLocation RAY_TEXTURE = new ResourceLocation(Wizardry.MODID,
"textures/entity/black_hole/ray.png");
private static final ResourceLocation CENTRE_TEXTURE = new ResourceLocation(Wizardry.MODID,
"textures/entity/black_hole/centre.png");
public RenderBlackHole(RenderManager renderManager){
super(renderManager);
}
@Override
public void doRender(EntityBlackHole entity, double x, double y, double z, float entityYaw, float partialTicks){
GlStateManager.pushMatrix();
GlStateManager.disableCull();
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GlStateManager.shadeModel(GL11.GL_SMOOTH);
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
RenderHelper.disableStandardItemLighting();
GlStateManager.translate(x, y, z);
// float pitch = (float) Math.toDegrees(Math.atan(y/(x*x+z*z)));
// float yaw = (float) Math.toDegrees(Math.atan(x/z));
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
int animationTicks = 10;
float age = entity.ticksExisted + partialTicks;
float s = age < animationTicks ? age/animationTicks : MathHelper.clamp((entity.lifetime - age) / animationTicks, 0, 1);
s = (float)Math.pow(s, 0.4); // Smooths the animation
GlStateManager.scale(s, s, s);
this.bindTexture(RAY_TEXTURE);
// In theory this stuff should sort the rays into the correct render order based on the distance from
// the 'camera' (i.e. the player's viewpoint)
// In the end it was easier to do away with the openGL rotation because for some reason it produced
// coordinates which were inconsistent with my calculated ones. Since I know those will give the desired
// effect anyway, I just used them directly instead.
ArrayList<RayHelper> rays = new ArrayList<>(1);
for(int j = 0; j < 30; j++){
float scale = 3.0f;
int a = entity.randomiser[j];
int b = entity.randomiser2[j];
int sliceAngle = 20 + a;
double x1 = scale * MathHelper.sin((entity.ticksExisted + 40 * j) * ((float)Math.PI / 180f));
// double y1 = 0.7*MathHelper.cos((blackhole.timer - 40*j)*(Math.PI/180))*j/10;
double z1 = scale * MathHelper.cos((entity.ticksExisted + 40 * j) * ((float)Math.PI / 180));
double x2 = scale * MathHelper.sin((entity.ticksExisted + 40 * j - sliceAngle) * ((float)Math.PI / 180));
// double y2 = 0.7*MathHelper.sin((blackhole.timer - 40*j)*(Math.PI/180))*j/10;
double z2 = scale * MathHelper.cos((entity.ticksExisted + 40 * j - sliceAngle) * ((float)Math.PI / 180));
double absoluteX = x1 * MathHelper.cos(31 * b);
double absoluteY = z1 * MathHelper.sin(31 * a) + x1 * MathHelper.cos(31 * a) * MathHelper.sin(31 * b);
double absoluteZ = z1 * MathHelper.cos(31 * a);
double absoluteX2 = x2 * MathHelper.cos(31 * b);
double absoluteY2 = z2 * MathHelper.sin(31 * a) + x2 * MathHelper.cos(31 * a) * MathHelper.sin(31 * b);
double absoluteZ2 = z2 * MathHelper.cos(31 * a);
/* buffer.begin(0, DefaultVertexFormats.POSITION_TEX);
*
* tessellator.setColorOpaque(255, 255, 255); GL11.glPointSize(5);
*
* tessellator.addVertex(absoluteX-x, 0, 0); tessellator.addVertex(0, absoluteY-y, 0);
* tessellator.addVertex(0, 0, absoluteZ-z);
*
* tessellator.draw(); */
rays.add(new RayHelper(j, absoluteX, absoluteY, absoluteZ, absoluteX2, absoluteY2, absoluteZ2, x, y, z));
}
Collections.sort(rays);
for(RayHelper ray : rays){
GlStateManager.pushMatrix();
// GlStateManager.rotate(31*blackhole.randomiser[ray.ordinal], 1, 0, 0);
// GlStateManager.rotate(31*blackhole.randomiser2[ray.ordinal], 0, 0, 1);
buffer.begin(5, DefaultVertexFormats.POSITION_TEX);
// tessellator.setColorRGBA(255, 255, 255, 0);
buffer.pos(0, 0, 0).tex(0, 0).endVertex();
buffer.pos(0, 0, 0).tex(0, 1).endVertex();
// tessellator.setColorRGBA(0, 0, 0, 255);
buffer.pos(ray.x1, ray.y1, ray.z1).tex(1, 0).endVertex();
buffer.pos(ray.x2, ray.y2, ray.z2).tex(1, 1).endVertex();
tessellator.draw();
GlStateManager.popMatrix();
}
GlStateManager.pushMatrix();
/* Deprecated in favour of particle style method. GlStateManager.rotate(yaw, 0, 1, 0); // GL transformations are
* relative, hence only x rotation if(z < 0){ GlStateManager.rotate(pitch, 1, 0, 0); }else{
* GlStateManager.rotate(-1*pitch, 1, 0, 0); } */
// Renders the aura effect
// This counteracts the reverse rotation behaviour when in front f5 view. Vanilla now has this fix too.
float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2 ? this.renderManager.playerViewX
: -this.renderManager.playerViewX;
GlStateManager.rotate(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
this.bindTexture(CENTRE_TEXTURE);
buffer.pos(-0.4, 0.4, 0).tex(0, 0).endVertex();
buffer.pos(0.4, 0.4, 0).tex(1, 0).endVertex();
buffer.pos(0.4, -0.4, 0).tex(1, 1).endVertex();
buffer.pos(-0.4, -0.4, 0).tex(0, 1).endVertex();
tessellator.draw();
GlStateManager.popMatrix();
GlStateManager.shadeModel(GL11.GL_FLAT);
GlStateManager.enableCull();
GlStateManager.disableBlend();
GlStateManager.enableLighting();
RenderHelper.enableStandardItemLighting();
GlStateManager.popMatrix();
}
@Override
protected ResourceLocation getEntityTexture(EntityBlackHole entity){
return RAY_TEXTURE;
}
}
@@ -0,0 +1,24 @@
package electroblob.wizardry.client.renderer.entity;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
public class RenderBlank extends Render<Entity> {
public RenderBlank(RenderManager renderManager){
super(renderManager);
}
@Override
public void doRender(Entity entity, double d0, double d1, double d2, float f, float f1){
}
@Override
protected ResourceLocation getEntityTexture(Entity entity){
return null;
}
}
@@ -0,0 +1,105 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.construct.EntityBubble;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
public class RenderBubble extends Render<EntityBubble> {
private static final ResourceLocation PARTICLE_TEXTURES = new ResourceLocation("textures/particle/particles.png");
private static final ResourceLocation ENTRAPMENT_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/entity/entrapment.png");
public RenderBubble(RenderManager renderManager){
super(renderManager);
}
@Override
public void doRender(EntityBubble entity, double par2, double par4, double par6, float par8, float par9){
GlStateManager.pushMatrix();
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
float yOffset = 0;
Entity rider = WizardryUtilities.getRider(entity);
if(rider != null){
yOffset = rider.height / 2;
}
GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6);
this.bindTexture(entity.isDarkOrb ? ENTRAPMENT_TEXTURE : PARTICLE_TEXTURES);
float f6 = 1.0F;
float f7 = 0.5F;
float f8 = 0.5F;
if(entity.isDarkOrb){
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
}else{
int j = entity.getBrightnessForRender();
int k = j % 65536;
int l = j / 65536;
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)k / 1.0F, (float)l / 1.0F);
}
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
// This counteracts the reverse rotation behaviour when in front f5 view.
// Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example.
float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2 ? this.renderManager.playerViewX
: -this.renderManager.playerViewX;
GlStateManager.rotate(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F);
float f11 = 3.0F;
GlStateManager.scale(f11, f11, f11);
double pixelwidth = (1.0d / 128);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
// tessellator.setColorRGBA_I(k1, 128);
// buffer.normal(0.0F, 1.0F, 0.0F);
if(entity.isDarkOrb){
buffer.pos(0.0F - f7, 0.0F - f8, 0.0D).tex(0, 1).endVertex();
buffer.pos(f6 - f7, 0.0F - f8, 0.0D).tex(1, 1).endVertex();
buffer.pos(f6 - f7, 1.0F - f8, 0.0D).tex(1, 0).endVertex();
buffer.pos(0.0F - f7, 1.0F - f8, 0.0D).tex(0, 0).endVertex();
}else{
buffer.pos(0.0F - f7, 0.0F - f8, 0.0D).tex(pixelwidth, pixelwidth * 24).endVertex();
buffer.pos(f6 - f7, 0.0F - f8, 0.0D).tex(pixelwidth * 8, pixelwidth * 24).endVertex();
buffer.pos(f6 - f7, 1.0F - f8, 0.0D).tex(pixelwidth * 8, pixelwidth * 17).endVertex();
buffer.pos(0.0F - f7, 1.0F - f8, 0.0D).tex(pixelwidth, pixelwidth * 17).endVertex();
}
tessellator.draw();
GlStateManager.disableBlend();
if(entity.isDarkOrb) GlStateManager.enableLighting();
GlStateManager.disableRescaleNormal();
GlStateManager.popMatrix();
}
@Override
protected ResourceLocation getEntityTexture(EntityBubble entity){
return null;
}
}
@@ -0,0 +1,73 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.construct.EntityDecay;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
public class RenderDecay extends Render<EntityDecay> {
private static final ResourceLocation[] TEXTURES = new ResourceLocation[10];
public RenderDecay(RenderManager renderManager){
super(renderManager);
for(int i = 0; i < 10; i++){
TEXTURES[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/decay/decay_" + i + ".png");
}
}
@Override
public void doRender(EntityDecay entity, double par2, double par4, double par6, float par8, float par9){
GlStateManager.pushMatrix();
GlStateManager.enableBlend();
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
float yOffset = 0;
GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6);
this.bindTexture(TEXTURES[((EntityDecay)entity).textureIndex]);
float f6 = 1.0F;
float f7 = 0.5F;
float f8 = 0.5F;
GlStateManager.rotate(-90, 1, 0, 0);
float scale = 2 * Math.min(1, (float)(entity.lifetime - entity.ticksExisted) / 50f);
GlStateManager.scale(scale, scale, scale);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
// tessellator.setColorRGBA_I(k1, 128);
// buffer.normal(0.0F, 1.0F, 0.0F);
buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex();
buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex();
buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex();
buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex();
tessellator.draw();
GlStateManager.disableBlend();
GlStateManager.enableLighting();
GlStateManager.disableRescaleNormal();
GlStateManager.popMatrix();
}
@Override
protected ResourceLocation getEntityTexture(EntityDecay entity){
return null;
}
}
@@ -0,0 +1,109 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.living.EntityDecoy;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderBiped;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//@SideOnly(Side.CLIENT)
public class RenderDecoy extends RenderBiped<EntityDecoy> {
private static final ResourceLocation steveTextures = new ResourceLocation("textures/entity/steve.png");
private static final Method getEntityTexture = ObfuscationReflectionHelper.findMethod(Render.class, "func_110775_a",
ResourceLocation.class, Entity.class); // Generic parameter T is erased to Entity at runtime.
public RenderDecoy(RenderManager manager){
super(manager, new ModelBiped(0.0f), 0.5f);
}
@Override
public void doRender(EntityDecoy entity, double x, double y, double z, float entityYaw, float partialTicks){
if(entity.getCaster() != null){
this.renderName(entity, x, y, z);
// Save relevant animation fields from the caster to local variables
float pitch = entity.getCaster().rotationPitch;
float prevPitch = entity.getCaster().prevRotationPitch;
float swing = entity.getCaster().swingProgress;
float prevSwing = entity.getCaster().prevSwingProgress;
float yawOffset = entity.getCaster().renderYawOffset;
float prevYawOffset = entity.getCaster().prevRenderYawOffset;
float yaw = entity.getCaster().rotationYawHead;
float prevYaw = entity.getCaster().prevRotationYawHead;
float limbSwing = entity.getCaster().limbSwing;
float limbSwingAmount = entity.getCaster().limbSwingAmount;
float prevLimbSwingAmount = entity.getCaster().prevLimbSwingAmount;
int hurtTime = entity.getCaster().hurtTime;
boolean sneak = entity.getCaster().isSneaking();
Entity mount = entity.getCaster().getRidingEntity();
// Assign decoy's animation fields to the caster
entity.getCaster().rotationPitch = entity.rotationPitch;
entity.getCaster().prevRotationPitch = entity.prevRotationPitch;
entity.getCaster().swingProgress = entity.swingProgress;
entity.getCaster().prevSwingProgress = entity.prevSwingProgress;
entity.getCaster().renderYawOffset = entity.renderYawOffset;
entity.getCaster().prevRenderYawOffset = entity.prevRenderYawOffset;
entity.getCaster().rotationYawHead = entity.rotationYawHead;
entity.getCaster().prevRotationYawHead = entity.prevRotationYawHead;
entity.getCaster().limbSwing = entity.limbSwing;
entity.getCaster().limbSwingAmount = entity.limbSwingAmount;
entity.getCaster().prevLimbSwingAmount = entity.prevLimbSwingAmount;
entity.getCaster().hurtTime = entity.hurtTime;
entity.getCaster().setSneaking(false); // Decoys can't sneak FIXME Not working!
entity.getCaster().dismountRidingEntity(); // Decoys can't ride anything
// Do the rendering
renderManager.getEntityRenderObject(entity.getCaster()).doRender(entity.getCaster(), x, y, z, entityYaw,
partialTicks);
// Reset caster's animation fields to their original values
entity.getCaster().rotationPitch = pitch;
entity.getCaster().prevRotationPitch = prevPitch;
entity.getCaster().swingProgress = swing;
entity.getCaster().prevSwingProgress = prevSwing;
entity.getCaster().renderYawOffset = yawOffset;
entity.getCaster().prevRenderYawOffset = prevYawOffset;
entity.getCaster().rotationYawHead = yaw;
entity.getCaster().prevRotationYawHead = prevYaw;
entity.getCaster().limbSwing = limbSwing;
entity.getCaster().limbSwingAmount = limbSwingAmount;
entity.getCaster().prevLimbSwingAmount = prevLimbSwingAmount;
entity.getCaster().hurtTime = hurtTime;
entity.getCaster().setSneaking(sneak);
if(mount != null) entity.getCaster().startRiding(mount);
}else{
super.doRender(entity, x, y, z, entityYaw, partialTicks);
}
}
@Override
protected ResourceLocation getEntityTexture(EntityDecoy entity){
if(entity.getCaster() != null){
try{
return (ResourceLocation)getEntityTexture
.invoke(renderManager.getEntityRenderObject(entity.getCaster()));
}catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
| ClassCastException e){
Wizardry.logger
.error("Error while reflectively calling Render#getEntityTexture as part of decoy rendering");
e.printStackTrace();
}
}
// Fallback to steve textures
return steveTextures;
}
}
@@ -0,0 +1,32 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.model.ModelWizard;
import electroblob.wizardry.entity.living.EntityEvilWizard;
import net.minecraft.client.renderer.entity.RenderBiped;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.entity.layers.LayerBipedArmor;
import net.minecraft.util.ResourceLocation;
//@SideOnly(Side.CLIENT)
public class RenderEvilWizard extends RenderBiped<EntityEvilWizard> {
static final ResourceLocation[] TEXTURES = new ResourceLocation[6];
public RenderEvilWizard(RenderManager renderManager){
super(renderManager, new ModelWizard(), 0.5F);
for(int i = 0; i < 6; i++){
TEXTURES[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/evil_wizard/evil_wizard_" + i + ".png");
}
// Just using the default without overriding models, since the armour sets its own model anyway.
this.addLayer(new LayerBipedArmor(this));
}
@Override
protected ResourceLocation getEntityTexture(EntityEvilWizard wizard){
return TEXTURES[wizard.textureIndex];
}
}
@@ -0,0 +1,186 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.entity.construct.EntityFireRing;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.init.Blocks;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
public class RenderFireRing extends Render<EntityFireRing> {
private final ResourceLocation texture;
private float scale = 1.0f;
public RenderFireRing(RenderManager renderManager, ResourceLocation texture, float scale){
super(renderManager);
this.texture = texture;
this.scale = scale;
}
@Override
public void doRender(EntityFireRing entity, double par2, double par4, double par6, float par8, float par9){
GlStateManager.pushMatrix();
GlStateManager.enableBlend();
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
float yOffset = 0;
GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6);
this.bindTexture(texture);
float f6 = 1.0F;
float f7 = 0.5F;
float f8 = 0.5F;
GlStateManager.rotate(-90, 1, 0, 0);
GlStateManager.scale(scale, scale, scale);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex();
buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex();
buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex();
buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex();
tessellator.draw();
GlStateManager.disableBlend();
GlStateManager.enableLighting();
GlStateManager.disableRescaleNormal();
GlStateManager.popMatrix();
// Fire
GlStateManager.disableLighting();
TextureAtlasSprite icon = Minecraft.getMinecraft().getBlockRendererDispatcher()
.getModelForState(Blocks.FIRE.getDefaultState()).getParticleTexture();
int sides = 16;
float height = 1.0f;
for(int k = 0; k < sides; k++){
GlStateManager.pushMatrix();
GlStateManager.translate((float)par2, (float)par4 + 0.05f, (float)par6);
float f1 = 1.0f;
GlStateManager.scale(f1, f1, f1);
float f2 = 0.5F;
float f3 = 0.0F;
float f4 = 0.2f;
float f5 = (float)(entity.posY - entity.getEntityBoundingBox().minY);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
float f61 = 0.0F;
int i = 0;
GlStateManager.rotate((360f / (float)sides) * k, 0, 1, 0);
GlStateManager.translate(0, 0, -2.3f);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
while(f4 > 0.0F){
this.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
float f71 = icon.getMinU();
float f81 = icon.getMinV();
float f9 = icon.getMaxU();
float f10 = icon.getMaxV();
if(i / 2 % 2 == 0){
float f11 = f9;
f9 = f71;
f71 = f11;
}
buffer.pos((double)(f2 - f3), (double)(0.0F - f5), (double)f61).tex((double)f9, (double)f10)
.endVertex();
buffer.pos((double)(-f2 - f3), (double)(0.0F - f5), (double)f61).tex((double)f71, (double)f10)
.endVertex();
buffer.pos((double)(-f2 - f3), (double)(height - f5), (double)f61).tex((double)f71, (double)f81)
.endVertex();
buffer.pos((double)(f2 - f3), (double)(height - f5), (double)f61).tex((double)f9, (double)f81)
.endVertex();
f4 -= 0.45F;
f5 -= 0.45F;
f2 *= 0.9F;
f61 += 0.03F;
++i;
}
tessellator.draw();
GlStateManager.popMatrix();
}
for(int k = 0; k < sides; k++){
GlStateManager.pushMatrix();
GlStateManager.translate((float)par2, (float)par4 + 0.05f, (float)par6);
float f1 = 1.0f;
GlStateManager.scale(f1, f1, f1);
float f2 = 0.5F;
float f3 = 0.0F;
float f4 = 0.2f;
float f5 = (float)(entity.posY - entity.getEntityBoundingBox().minY);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
float f61 = 0.0F;
int i = 0;
GlStateManager.rotate((360f / (float)sides) * k, 0, 1, 0);
GlStateManager.translate(0, 0, 2.3f);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
while(f4 > 0.0F){
this.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
float f71 = icon.getMinU();
float f81 = icon.getMinV();
float f9 = icon.getMaxU();
float f10 = icon.getMaxV();
if(i / 2 % 2 == 0){
float f11 = f9;
f9 = f71;
f71 = f11;
}
buffer.pos((double)(f2 - f3), (double)(0.0F - f5), (double)f61).tex((double)f9, (double)f10)
.endVertex();
buffer.pos((double)(-f2 - f3), (double)(0.0F - f5), (double)f61).tex((double)f71, (double)f10)
.endVertex();
buffer.pos((double)(-f2 - f3), (double)(height - f5), (double)f61).tex((double)f71, (double)f81)
.endVertex();
buffer.pos((double)(f2 - f3), (double)(height - f5), (double)f61).tex((double)f9, (double)f81)
.endVertex();
f4 -= 0.45F;
f5 -= 0.45F;
f2 *= 0.9F;
f61 += 0.03F;
++i;
}
tessellator.draw();
GlStateManager.popMatrix();
}
GlStateManager.enableLighting();
}
@Override
protected ResourceLocation getEntityTexture(EntityFireRing entity){
return null;
}
}
@@ -0,0 +1,135 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.projectile.EntityForceArrow;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import org.lwjgl.opengl.GL11;
//@SideOnly(Side.CLIENT)
public class RenderForceArrow extends Render<EntityForceArrow> {
private static final ResourceLocation arrowTextures = new ResourceLocation(Wizardry.MODID,
"textures/entity/force_arrow.png");
public RenderForceArrow(RenderManager renderManager){
super(renderManager);
}
@Override
public void doRender(EntityForceArrow arrow, double par2, double par4, double par6, float par8, float par9){
this.bindEntityTexture(arrow);
GlStateManager.pushMatrix();
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GlStateManager.translate((float)par2, (float)par4, (float)par6);
GlStateManager.rotate(arrow.prevRotationYaw + (arrow.rotationYaw - arrow.prevRotationYaw) * par9 - 90.0F, 0.0F,
1.0F, 0.0F);
GlStateManager.rotate(arrow.prevRotationPitch + (arrow.rotationPitch - arrow.prevRotationPitch) * par9, 0.0F,
0.0F, 1.0F);
GlStateManager.rotate(180, 0, 1, 0);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
float pixel = 1.0f / 32.0f;
float u1 = 0.0f;
float u2 = pixel * 14;
float v1 = 0.0f;
float v2 = pixel * 7;
float u3 = pixel * 16;
float u4 = 1.0f;
float v3 = 0.0f;
float v4 = pixel * 16;
float u5 = 0.0f;
float u6 = pixel * 7;
float v5 = pixel * 25;
float v6 = 1.0f;
float scale = 0.05625F;
float f11 = 0.0f;
GlStateManager.enableRescaleNormal();
// f11 = (float)par1EntityArrow.arrowShake - par9;
if(f11 > 0.0F){
float f12 = -MathHelper.sin(f11 * 3.0F) * f11;
GlStateManager.rotate(f12, 0.0F, 0.0F, 1.0F);
}
scale *= 0.8f;
GlStateManager.rotate(45.0F, 1.0F, 0.0F, 0.0F);
GlStateManager.scale(scale, scale, scale);
GlStateManager.translate(-4.0F, 0.0F, 0.0F);
// Front
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-5, 3.5, -3.5).tex((double)u5, (double)v5).endVertex();
buffer.pos(-5, 3.5, 3.5).tex((double)u6, (double)v5).endVertex();
buffer.pos(-5, -3.5, 3.5).tex((double)u6, (double)v6).endVertex();
buffer.pos(-5, -3.5, -3.5).tex((double)u5, (double)v6).endVertex();
tessellator.draw();
// Back
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-5, -3.5, -3.5).tex((double)u5, (double)v6).endVertex();
buffer.pos(-5, -3.5, 3.5).tex((double)u6, (double)v6).endVertex();
buffer.pos(-5, 3.5, 3.5).tex((double)u6, (double)v5).endVertex();
buffer.pos(-5, 3.5, -3.5).tex((double)u5, (double)v5).endVertex();
tessellator.draw();
// Rings
for(int i = 0; i < 5; i++){
GlStateManager.color(1, 1, 1, 1 - i * 0.2f);
double j = i + ((double)arrow.ticksExisted % 3) / 3;
double width = 2.0d + (Math.sqrt(j * 2) - 0.6) * 2;
GL11.glNormal3f(scale, 0.0F, 0.0F);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-10 + j * 4, -width, -width).tex((double)u3, (double)v3).endVertex();
buffer.pos(-10 + j * 4, -width, width).tex((double)u4, (double)v3).endVertex();
buffer.pos(-10 + j * 4, width, width).tex((double)u4, (double)v4).endVertex();
buffer.pos(-10 + j * 4, width, -width).tex((double)u3, (double)v4).endVertex();
tessellator.draw();
GL11.glNormal3f(-scale, 0.0F, 0.0F);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-10 + j * 4, width, -width).tex((double)u3, (double)v3).endVertex();
buffer.pos(-10 + j * 4, width, width).tex((double)u4, (double)v3).endVertex();
buffer.pos(-10 + j * 4, -width, width).tex((double)u4, (double)v4).endVertex();
buffer.pos(-10 + j * 4, -width, -width).tex((double)u3, (double)v4).endVertex();
tessellator.draw();
}
GlStateManager.color(1, 1, 1, 1);
// Sides
for(int i = 0; i < 4; ++i){
GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F);
GL11.glNormal3f(0.0F, 0.0F, scale);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-10.0D, -4.0D, 0.0D).tex((double)u1, (double)v1).endVertex();
buffer.pos(10.0D, -4.0D, 0.0D).tex((double)u2, (double)v1).endVertex();
buffer.pos(10.0D, 4.0D, 0.0D).tex((double)u2, (double)v2).endVertex();
buffer.pos(-10.0D, 4.0D, 0.0D).tex((double)u1, (double)v2).endVertex();
tessellator.draw();
}
GlStateManager.disableBlend();
GlStateManager.disableRescaleNormal();
GlStateManager.enableLighting();
GlStateManager.popMatrix();
}
@Override
protected ResourceLocation getEntityTexture(EntityForceArrow par1Entity){
return arrowTextures;
}
}
@@ -0,0 +1,124 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.entity.construct.EntityForcefield;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import org.lwjgl.opengl.GL11;
public class RenderForcefield extends Render<EntityForcefield> {
private static final float EXPANSION_TIME = 3;
public RenderForcefield(RenderManager renderManager){
super(renderManager);
}
@Override
public void doRender(EntityForcefield entity, double x, double y, double z, float yaw, float partialTicks){
// For now we're just using a UV sphere
GlStateManager.pushMatrix();
GlStateManager.disableLighting();
GlStateManager.enableBlend();
GlStateManager.disableTexture2D();
GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
GlStateManager.translate(x, y, z);
float latStep = (float)Math.PI/20;
float longStep = (float)Math.PI/20;
float pulse = MathHelper.sin((entity.ticksExisted + partialTicks)/10f);
float r = 0.35f, g = 0.55f + 0.05f * pulse, b = 1;
float radius = entity.getRadius();
float a = 0.5f;
if(entity.ticksExisted > entity.lifetime - EXPANSION_TIME){
radius *= 1 + 0.2f * (entity.ticksExisted + partialTicks - (entity.lifetime - EXPANSION_TIME))/EXPANSION_TIME;
a *= Math.max(0, 1 - (entity.ticksExisted + partialTicks - (entity.lifetime - EXPANSION_TIME))/EXPANSION_TIME);
}else if(entity.ticksExisted < EXPANSION_TIME){
radius *= 1 - (EXPANSION_TIME - entity.ticksExisted - partialTicks)/EXPANSION_TIME;
a *= 1 - (EXPANSION_TIME - entity.ticksExisted - partialTicks)/EXPANSION_TIME;
}
// Draw the inside first
drawSphere(radius - 0.1f - 0.025f * pulse, latStep, longStep, true, r, g, b, a);
drawSphere(radius - 0.1f - 0.025f * pulse, latStep, longStep, false, 1, 1, 1, a);
drawSphere(radius, latStep, longStep, false, r, g, b, 0.7f * a);
GlStateManager.enableTexture2D();
GlStateManager.enableLighting();
GlStateManager.disableBlend();
GlStateManager.popMatrix();
}
@Override
protected ResourceLocation getEntityTexture(EntityForcefield entity){
return null;
}
/**
* Draws a sphere (using lat/long triangles) with the given parameters.
* @param radius The radius of the sphere.
* @param latStep The latitude step; smaller is smoother but increases performance cost.
* @param longStep The longitude step; smaller is smoother but increases performance cost.
* @param inside Whether to draw the outside or the inside of the sphere.
* @param r The red component of the sphere colour.
* @param g The green component of the sphere colour.
* @param b The blue component of the sphere colour.
* @param a The alpha component of the sphere colour.
*/
private static void drawSphere(float radius, float latStep, float longStep, boolean inside, float r, float g, float b, float a){
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_COLOR);
boolean goingUp = inside;
buffer.pos(0, goingUp ? -radius : radius, 0).color(r, g, b, a).endVertex(); // Start at the north pole
for(float longitude = -(float)Math.PI; longitude <= (float)Math.PI; longitude += longStep){
// Leave the poles out since they only have a single point per stack instead of two
for(float theta = (float)Math.PI/2 - latStep; theta >= -(float)Math.PI/2 + latStep; theta -= latStep){
float latitude = goingUp ? -theta : theta;
float hRadius = radius * MathHelper.cos(latitude);
float vy = radius * MathHelper.sin(latitude);
float vx = hRadius * MathHelper.sin(longitude);
float vz = hRadius * MathHelper.cos(longitude);
buffer.pos(vx, vy, vz).color(r, g, b, a).endVertex();
vx = hRadius * MathHelper.sin(longitude + longStep);
vz = hRadius * MathHelper.cos(longitude + longStep);
buffer.pos(vx, vy, vz).color(r, g, b, a).endVertex();
}
// The next pole
buffer.pos(0, goingUp ? radius : -radius, 0).color(r, g, b, a).endVertex();
goingUp = !goingUp;
}
tessellator.draw();
}
}
@@ -0,0 +1,42 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.model.ModelHammer;
import electroblob.wizardry.entity.construct.EntityHammer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.util.ResourceLocation;
public class RenderHammer extends Render<EntityHammer> {
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID,
"textures/entity/lightning_hammer.png");
private ModelHammer model = new ModelHammer();
public RenderHammer(RenderManager renderManager){
super(renderManager);
}
@Override
public void doRender(EntityHammer entity, double x, double y, double z, float yaw, float partialTicks){
GlStateManager.pushMatrix();
GlStateManager.translate(x, y + 1.5, z);
GlStateManager.rotate(180, 0F, 0F, 1F);
GlStateManager.rotate(yaw, 0, 1, 0);
GlStateManager.rotate(entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * partialTicks, 0, 0, 1);
this.bindTexture(texture);
model.render(entity, 0, 0, 0, 0, 0, 0.0625f);
GlStateManager.popMatrix();
}
@Override
protected ResourceLocation getEntityTexture(EntityHammer entity){
return texture;
}
}
@@ -0,0 +1,38 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.model.ModelIceGiant;
import electroblob.wizardry.entity.living.EntityIceGiant;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.RenderLiving;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.util.ResourceLocation;
//@SideOnly(Side.CLIENT)
public class RenderIceGiant extends RenderLiving<EntityIceGiant> {
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID,
"textures/entity/ice_giant.png");
public RenderIceGiant(RenderManager renderManager){
super(renderManager, new ModelIceGiant(), 0.5F);
}
@Override
protected ResourceLocation getEntityTexture(EntityIceGiant entity){
return texture;
}
@Override
protected void applyRotations(EntityIceGiant entityLiving, float pitch, float yaw, float partialTicks){
super.applyRotations(entityLiving, pitch, yaw, partialTicks);
if((double)entityLiving.limbSwingAmount >= 0.01D){
float f3 = 13.0F;
float f4 = entityLiving.limbSwing - entityLiving.limbSwingAmount * (1.0F - partialTicks) + 6.0F;
float f5 = (Math.abs(f4 % f3 - f3 * 0.5F) - f3 * 0.25F) / (f3 * 0.25F);
GlStateManager.rotate(6.5F * f5, 0.0F, 0.0F, 1.0F);
}
}
}
@@ -0,0 +1,85 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.construct.EntityIceSpike;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
public class RenderIceSpike extends Render<EntityIceSpike> {
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID,
"textures/entity/ice_spike.png");
public RenderIceSpike(RenderManager renderManager){
super(renderManager);
}
@Override
public void doRender(EntityIceSpike entity, double x, double y, double z, float yaw, float partialTickTime){
GlStateManager.pushMatrix();
GlStateManager.translate((float)x, (float)y, (float)z);
GlStateManager.rotate(entity.rotationYaw - 90.0F, 0.0F, 1.0F, 0.0F);
GlStateManager.rotate(entity.rotationPitch - 90, 0.0F, 0.0F, 1.0F);
GlStateManager.disableLighting();
int j = entity.getBrightnessForRender();
int k = j % 65536;
int l = j / 65536;
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)k / 1.0F, (float)l / 1.0F);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
bindTexture(texture);
// West face
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(0, 0, 0.5).tex(1, 1).endVertex();
buffer.pos(0, 1, 0.5).tex(1, 0).endVertex();
buffer.pos(0, 1, -0.5).tex(0, 0).endVertex();
buffer.pos(0, 0, -0.5).tex(0, 1).endVertex();
tessellator.draw();
// South face
buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX);
buffer.pos(0.5, 0, 0).tex(1, 1).endVertex();
buffer.pos(0.5, 1, 0).tex(1, 0).endVertex();
buffer.pos(-0.5, 1, 0).tex(0, 0).endVertex();
buffer.pos(-0.5, 0, 0).tex(0, 1).endVertex();
tessellator.draw();
// East face
buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX);
buffer.pos(0, 0, -0.5).tex(0, 1).endVertex();
buffer.pos(0, 1, -0.5).tex(0, 0).endVertex();
buffer.pos(0, 1, 0.5).tex(1, 0).endVertex();
buffer.pos(0, 0, 0.5).tex(1, 1).endVertex();
tessellator.draw();
// North face
buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX);
buffer.pos(-0.5, 0, 0).tex(0, 1).endVertex();
buffer.pos(-0.5, 1, 0).tex(0, 0).endVertex();
buffer.pos(0.5, 1, 0).tex(1, 0).endVertex();
buffer.pos(0.5, 0, 0).tex(1, 1).endVertex();
tessellator.draw();
GlStateManager.enableLighting();
GlStateManager.popMatrix();
}
@Override
protected ResourceLocation getEntityTexture(EntityIceSpike entity){
return texture;
}
}
@@ -0,0 +1,81 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.entity.projectile.EntityLightningDisc;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
public class RenderLightningDisc extends Render<EntityLightningDisc> {
private final ResourceLocation texture;
private float scale = 1.0f;
public RenderLightningDisc(RenderManager renderManager, ResourceLocation texture, float scale){
super(renderManager);
this.texture = texture;
this.scale = scale;
}
@Override
public void doRender(EntityLightningDisc entity, double par2, double par4, double par6, float par8, float par9){
GlStateManager.pushMatrix();
GlStateManager.enableBlend();
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
float yOffset = 0;
GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6);
this.bindTexture(texture);
float f6 = 1.0F;
float f7 = 0.5F;
float f8 = 0.5F;
GlStateManager.rotate(-90, 1, 0, 0);
GlStateManager.rotate(entity.ticksExisted * 8, 0, 0, 1);
GlStateManager.scale(scale, scale, scale);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
// tessellator.setColorRGBA_I(k1, 128);
// buffer.normal(0.0F, 1.0F, 0.0F);
buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex();
buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex();
buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex();
buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex();
tessellator.draw();
buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX);
// buffer.normal(0.0F, 1.0F, 0.0F);
buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex();
buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex();
buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex();
buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex();
tessellator.draw();
GlStateManager.disableBlend();
GlStateManager.enableLighting();
GlStateManager.disableRescaleNormal();
GlStateManager.popMatrix();
}
@Override
protected ResourceLocation getEntityTexture(EntityLightningDisc entity){
return null;
}
}
@@ -0,0 +1,120 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.entity.projectile.EntityMagicArrow;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import org.lwjgl.opengl.GL11;
//@SideOnly(Side.CLIENT)
public class RenderMagicArrow extends Render<EntityMagicArrow> {
private final ResourceLocation texture;
private boolean blend;
private boolean renderEnds;
private double length = 8.0, width = 2.0;
private int pixelsLong = 16, pixelsWide = 5;
public RenderMagicArrow(RenderManager renderManager, ResourceLocation texture, boolean blend, double length,
double width, int pixelsLong, int pixelsWide, boolean renderEnds){
super(renderManager);
this.texture = texture;
this.blend = blend;
this.renderEnds = renderEnds;
this.length = length;
this.width = width;
this.pixelsLong = pixelsLong;
this.pixelsWide = pixelsWide;
}
@Override
public void doRender(EntityMagicArrow entity, double par2, double par4, double par6, float par8, float par9){
this.bindEntityTexture(entity);
GlStateManager.pushMatrix();
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
if(this.blend){
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
}
GlStateManager.translate((float)par2, (float)par4, (float)par6);
GlStateManager.rotate(entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * par9 - 90.0F,
0.0F, 1.0F, 0.0F);
GlStateManager.rotate(entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * par9, 0.0F,
0.0F, 1.0F);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
float f2 = 0.0F;
float f3 = pixelsLong / 32.0F;
float f4 = 0.0F;
float f5 = pixelsWide / 32.0F;
float f6 = 0.0F;
float f7 = 0.15625F;
float f8 = (float)5 / 32.0F;
float f9 = (float)10 / 32.0F;
float f10 = 0.05625F;
float f11 = 0.0f;
GlStateManager.enableRescaleNormal();
// f11 = (float)par1EntityArrow.arrowShake - par9;
if(f11 > 0.0F){
float f12 = -MathHelper.sin(f11 * 3.0F) * f11;
GlStateManager.rotate(f12, 0.0F, 0.0F, 1.0F);
}
GlStateManager.rotate(45.0F, 1.0F, 0.0F, 0.0F);
GlStateManager.scale(f10, f10, f10);
GlStateManager.translate(-4.0F, 0.0F, 0.0F);
GL11.glNormal3f(f10, 0.0F, 0.0F);
if(renderEnds){
// Ends
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-7.0D, -width, -width).tex((double)f6, (double)f8).endVertex();
buffer.pos(-7.0D, -width, width).tex((double)f7, (double)f8).endVertex();
buffer.pos(-7.0D, width, width).tex((double)f7, (double)f9).endVertex();
buffer.pos(-7.0D, width, -width).tex((double)f6, (double)f9).endVertex();
tessellator.draw();
GL11.glNormal3f(-f10, 0.0F, 0.0F);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-7.0D, width, -width).tex((double)f6, (double)f8).endVertex();
buffer.pos(-7.0D, width, width).tex((double)f7, (double)f8).endVertex();
buffer.pos(-7.0D, -width, width).tex((double)f7, (double)f9).endVertex();
buffer.pos(-7.0D, -width, -width).tex((double)f6, (double)f9).endVertex();
tessellator.draw();
}
for(int i = 0; i < 4; ++i){
// Sides
GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F);
GL11.glNormal3f(0.0F, 0.0F, f10);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-length, -width, 0.0D).tex((double)f2, (double)f4).endVertex();
buffer.pos(length, -width, 0.0D).tex((double)f3, (double)f4).endVertex();
buffer.pos(length, width, 0.0D).tex((double)f3, (double)f5).endVertex();
buffer.pos(-length, width, 0.0D).tex((double)f2, (double)f5).endVertex();
tessellator.draw();
}
if(this.blend){
GlStateManager.disableBlend();
}
GlStateManager.disableRescaleNormal();
GlStateManager.enableLighting();
GlStateManager.popMatrix();
}
@Override
protected ResourceLocation getEntityTexture(EntityMagicArrow arrow){
return texture;
}
}
@@ -0,0 +1,49 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.model.ModelPhoenix;
import electroblob.wizardry.entity.living.EntityPhoenix;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.entity.RenderLiving;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
//@SideOnly(Side.CLIENT)
public class RenderPhoenix extends RenderLiving<EntityPhoenix> {
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/entity/phoenix.png");
public RenderPhoenix(RenderManager renderManager){
super(renderManager, new ModelPhoenix(), 1.0f);
}
@Override
protected ResourceLocation getEntityTexture(EntityPhoenix entity){
return texture;
}
@Override
protected void applyRotations(EntityPhoenix par1EntityPhoenix, float par2, float par3, float par4){
GlStateManager.translate(0.0F, -0.1F, 0.0F);
super.applyRotations(par1EntityPhoenix, par2, par3, par4);
}
@Override
public void doRender(EntityPhoenix phoenix, double par2, double par4, double par6, float par8, float par9){
GlStateManager.pushMatrix();
GlStateManager.disableLighting();
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
super.doRender(phoenix, par2, par4, par6, par8, par9);
GlStateManager.enableLighting();
GlStateManager.disableBlend();
GlStateManager.popMatrix();
}
}
@@ -0,0 +1,41 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.spell.Possession;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.client.event.RenderPlayerEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
@Mod.EventBusSubscriber(Side.CLIENT)
public class RenderPossessingPlayer {
@SubscribeEvent
@SuppressWarnings("unchecked") // Can't check it due to type erasure
public static void onRenderPlayerPreEvent(RenderPlayerEvent.Pre event){
EntityPlayer player = event.getEntityPlayer();
EntityLiving possessee = Possession.getPossessee(player);
if(possessee != null){
// I reject your renderer and substitute my own!
Render<EntityLiving> renderer = (Render<EntityLiving>)event.getRenderer().getRenderManager().entityRenderMap.get(possessee.getClass());
float yaw = player.prevRotationYaw + (player.rotationYaw - player.prevRotationYaw) * event.getPartialRenderTick();
possessee.swingProgress = player.swingProgress;
possessee.prevSwingProgress = player.prevSwingProgress;
possessee.renderYawOffset = player.renderYawOffset;
possessee.prevRenderYawOffset = player.prevRenderYawOffset;
possessee.rotationYawHead = player.rotationYawHead;
possessee.prevRotationYawHead = player.prevRotationYawHead;
possessee.rotationPitch = player.rotationPitch;
possessee.prevRotationPitch = player.prevRotationPitch;
possessee.limbSwing = player.limbSwing;
possessee.limbSwingAmount = player.limbSwingAmount;
possessee.prevLimbSwingAmount = player.prevLimbSwingAmount;
renderer.doRender(possessee, event.getX(), event.getY(), event.getZ(), yaw, event.getPartialRenderTick());
event.setCanceled(true);
}
}
}
@@ -0,0 +1,85 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.entity.projectile.EntityMagicProjectile;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
//@SideOnly(Side.CLIENT)
public class RenderProjectile extends Render<EntityMagicProjectile> {
private float scale;
private boolean blend = false;
private final ResourceLocation texture;
public RenderProjectile(RenderManager renderManager, float scale, ResourceLocation texture, boolean doBlending){
super(renderManager);
this.scale = scale;
this.texture = texture;
this.blend = doBlending;
}
@Override
public void doRender(EntityMagicProjectile entity, double par2, double par4, double par6, float par8, float par9){
GlStateManager.pushMatrix();
this.bindTexture(texture);
GlStateManager.translate((float)par2, (float)par4, (float)par6);
GlStateManager.enableRescaleNormal();
if(blend){
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
}
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
float f2 = this.scale;
GlStateManager.scale(f2 / 1.0F, f2 / 1.0F, f2 / 1.0F);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
float f3 = 0.0f;
float f4 = 1.0f;
float f5 = 0.0f;
float f6 = 1.0f;
float f7 = 1.0F;
float f8 = 0.5F;
float f9 = 0.25F;
// This counteracts the reverse rotation behaviour when in front f5 view.
// Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example.
float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2 ? this.renderManager.playerViewX
: -this.renderManager.playerViewX;
GlStateManager.rotate(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
// buffer.normal(0.0F, 1.0F, 0.0F);
buffer.pos((double)(0.0F - f8), (double)(0.0F - f9), 0.0D).tex((double)f3, (double)f6).endVertex();
buffer.pos((double)(f7 - f8), (double)(0.0F - f9), 0.0D).tex((double)f4, (double)f6).endVertex();
buffer.pos((double)(f7 - f8), (double)(1.0F - f9), 0.0D).tex((double)f4, (double)f5).endVertex();
buffer.pos((double)(0.0F - f8), (double)(1.0F - f9), 0.0D).tex((double)f3, (double)f5).endVertex();
tessellator.draw();
GlStateManager.disableRescaleNormal();
if(blend){
GlStateManager.disableBlend();
}
GlStateManager.enableLighting();
GlStateManager.popMatrix();
}
@Override
protected ResourceLocation getEntityTexture(EntityMagicProjectile par1Entity){
return texture;
}
}
@@ -0,0 +1,75 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.model.ModelRemnant;
import electroblob.wizardry.entity.living.EntityRemnant;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import javax.annotation.Nullable;
public class RenderRemnant extends Render<EntityRemnant> {
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/entity/remnant.png");
private final ModelRemnant model;
public RenderRemnant(RenderManager manager){
super(manager);
model = new ModelRemnant();
}
@Override
public void doRender(EntityRemnant entity, double x, double y, double z, float entityYaw, float partialTicks){
float age = (float)entity.ticksExisted + partialTicks;
GlStateManager.pushMatrix();
GlStateManager.translate((float)x, (float)y, (float)z);
this.bindTexture(TEXTURE);
// float whatIsThis = MathHelper.sin(age * 0.2F) / 2.0F + 0.5F;
// whatIsThis = whatIsThis * whatIsThis + whatIsThis;
if(this.renderOutlines){
GlStateManager.enableColorMaterial();
GlStateManager.enableOutlineMode(this.getTeamColor(entity));
}
float expansion = 0.9f;
if(entity.deathTime > 0){
float f = (entity.deathTime + partialTicks) * 0.25f;
f = 1 - (1 / (f + 1));
expansion -= f * 0.75f;
}else if(entity.hurtTime > 0){
float f = (entity.hurtTime - partialTicks) / entity.maxHurtTime;
// Neat bit of maths borrowed from the camera tilt effect when hurt
f = MathHelper.sin(f * f * f * f * (float)Math.PI);
expansion += f * 0.2f;
}
// if(entity.isAttacking()) s -= 0.4f;
float rotationSpeed = entity.isAttacking() ? 10 : 3;
this.model.render(entity, rotationSpeed, expansion, age, 0, 0, 0.0625f);
if(this.renderOutlines){
GlStateManager.disableOutlineMode();
GlStateManager.disableColorMaterial();
}
GlStateManager.popMatrix();
super.doRender(entity, x, y, z, entityYaw, partialTicks);
}
@Nullable
@Override
protected ResourceLocation getEntityTexture(EntityRemnant entity){
return TEXTURE;
}
}
@@ -0,0 +1,88 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.entity.construct.EntityHealAura;
import electroblob.wizardry.entity.construct.EntityMagicConstruct;
import electroblob.wizardry.util.AllyDesignationSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
public class RenderSigil extends Render<EntityMagicConstruct> {
private final ResourceLocation texture;
private float scale = 1.0f;
private boolean invisibleToEnemies;
public RenderSigil(RenderManager renderManager, ResourceLocation texture, float scale, boolean invisibleToEnemies){
super(renderManager);
this.texture = texture;
this.scale = scale;
this.invisibleToEnemies = invisibleToEnemies;
}
@Override
public void doRender(EntityMagicConstruct entity, double par2, double par4, double par6, float par8, float par9){
// Makes the sigil invisible to enemies of the player that created it
if(this.invisibleToEnemies){
// Unfortunately we can't access the caster's allies if they're not online, it only works the other way round
if(entity.getCaster() instanceof EntityPlayer && !AllyDesignationSystem
.isPlayerAlly((EntityPlayer)entity.getCaster(), Minecraft.getMinecraft().player)){
return;
}
}
GlStateManager.pushMatrix();
GlStateManager.enableBlend();
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
float yOffset = 0;
GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6);
this.bindTexture(texture);
float f6 = 1.0F;
float f7 = 0.5F;
float f8 = 0.5F;
GlStateManager.rotate(-90, 1, 0, 0);
// Healing aura rotates slowly
if(entity instanceof EntityHealAura) GlStateManager.rotate(entity.ticksExisted / 3.0f, 0, 0, 1);
GlStateManager.scale(scale, scale, scale);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
// tessellator.setColorRGBA_I(k1, 128);
// buffer.normal(0.0F, 1.0F, 0.0F);
buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex();
buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex();
buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex();
buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex();
tessellator.draw();
GlStateManager.disableBlend();
GlStateManager.enableLighting();
GlStateManager.disableRescaleNormal();
GlStateManager.popMatrix();
}
@Override
protected ResourceLocation getEntityTexture(EntityMagicConstruct entity){
return null;
}
}
@@ -0,0 +1,63 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.living.EntitySpiritHorse;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.RenderHorse;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.entity.passive.EntityHorse;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
//@SideOnly(Side.CLIENT)
public class RenderSpiritHorse extends RenderHorse {
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID,
"textures/entity/spirit_horse.png");
// private static final int GHOST_COPIES = 3;
// private static final float DECONVERGENCE = 0.35f;
public RenderSpiritHorse(RenderManager renderManager){
super(renderManager);
}
@Override
protected ResourceLocation getEntityTexture(EntityHorse entity){
return texture;
}
@Override
protected void preRenderCallback(EntityHorse horse, float partialTickTime){
super.preRenderCallback(horse, partialTickTime);
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
if(horse instanceof EntitySpiritHorse){ // Always true
GlStateManager.color(1, 1, 1, ((EntitySpiritHorse)horse).getOpacity());
}
}
@Override
public void doRender(EntityHorse entity, double x, double y, double z, float entityYaw, float partialTicks){
super.doRender(entity, x, y, z, entityYaw, partialTicks);
// double dx = (entity.posX - entity.prevPosX) * DECONVERGENCE;
// double dy = (entity.posY - entity.prevPosY) * DECONVERGENCE;
// double dz = (entity.posZ - entity.prevPosZ) * DECONVERGENCE;
// float dyaw = (entity.rotationYaw - entity.prevRotationYaw) * DECONVERGENCE;
//
// float opacity = 1;
// if(entity instanceof EntitySpiritHorse){ // Always true
// opacity = ((EntitySpiritHorse)entity).getOpacity();
// }
//
// for(int i = 0; i < GHOST_COPIES; i++){
//
// GlStateManager.color(1, 1, 1, opacity * (0.6f - (float)i/(GHOST_COPIES*2)));
//
// super.doRender(entity, x - dx * i, y - dy * i, z - dz * i, entityYaw - dyaw * i, partialTicks);
// }
}
}
@@ -0,0 +1,62 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.living.EntitySpiritWolf;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.entity.RenderWolf;
import net.minecraft.entity.passive.EntityWolf;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
//@SideOnly(Side.CLIENT)
public class RenderSpiritWolf extends RenderWolf {
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID,
"textures/entity/spirit_wolf.png");
// private static final int GHOST_COPIES = 3;
// private static final float DECONVERGENCE = 0.8f;
public RenderSpiritWolf(RenderManager renderManager){
super(renderManager);
}
@Override
protected ResourceLocation getEntityTexture(EntityWolf entity){
return texture;
}
@Override
protected void preRenderCallback(EntityWolf entity, float partialTickTime){
super.preRenderCallback(entity, partialTickTime);
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
if(entity instanceof EntitySpiritWolf){ // Always true
GlStateManager.color(1, 1, 1, ((EntitySpiritWolf)entity).getOpacity());
}
}
@Override
public void doRender(EntityWolf entity, double x, double y, double z, float entityYaw, float partialTicks){
super.doRender(entity, x, y, z, entityYaw, partialTicks);
// double dx = (entity.posX - entity.prevPosX) * DECONVERGENCE;
// double dy = (entity.posY - entity.prevPosY) * DECONVERGENCE;
// double dz = (entity.posZ - entity.prevPosZ) * DECONVERGENCE;
// float dyaw = (entity.rotationYaw - entity.prevRotationYaw) * DECONVERGENCE;
//
// float opacity = 1;
// if(entity instanceof EntitySpiritWolf){ // Always true
// opacity = ((EntitySpiritWolf)entity).getOpacity();
// }
//
// for(int i = 0; i < GHOST_COPIES; i++){
//
// GlStateManager.color(1, 1, 1, opacity * (0.6f - (float)i/(GHOST_COPIES*2)));
//
// super.doRender(entity, x - dx * i, y - dy * i, z - dz * i, entityYaw - dyaw * i, partialTicks);
// }
}
}
@@ -0,0 +1,25 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.client.renderer.entity.layers.LayerStrayMinionClothing;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.entity.RenderSkeleton;
import net.minecraft.entity.monster.AbstractSkeleton;
import net.minecraft.util.ResourceLocation;
/** This class also had to be copied for the same reason as {@link LayerStrayMinionClothing}. */
public class RenderStrayMinion extends RenderSkeleton {
private static final ResourceLocation STRAY_SKELETON_TEXTURES = new ResourceLocation("textures/entity/skeleton/stray.png");
public RenderStrayMinion(RenderManager manager){
super(manager);
this.addLayer(new LayerStrayMinionClothing(this)); // This is the only change
}
/**
* Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture.
*/
protected ResourceLocation getEntityTexture(AbstractSkeleton entity){
return STRAY_SKELETON_TEXTURES;
}
}
@@ -0,0 +1,32 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.model.ModelWizard;
import electroblob.wizardry.entity.living.EntityWizard;
import net.minecraft.client.renderer.entity.RenderBiped;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.entity.layers.LayerBipedArmor;
import net.minecraft.util.ResourceLocation;
//@SideOnly(Side.CLIENT)
public class RenderWizard extends RenderBiped<EntityWizard> {
static final ResourceLocation[] TEXTURES = new ResourceLocation[6];
public RenderWizard(RenderManager renderManager){
super(renderManager, new ModelWizard(), 0.5F);
for(int i = 0; i < 6; i++){
TEXTURES[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/wizard/wizard_" + i + ".png");
}
// Just using the default without overriding models, since the armour sets its own model anyway.
this.addLayer(new LayerBipedArmor(this));
}
@Override
protected ResourceLocation getEntityTexture(EntityWizard wizard){
return TEXTURES[wizard.textureIndex];
}
}
@@ -0,0 +1,21 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.entity.living.EntityBlazeMinion;
import net.minecraft.client.model.ModelBlaze;
import net.minecraft.client.renderer.entity.RenderLiving;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.util.ResourceLocation;
//@SideOnly(Side.CLIENT)
public class RenderWraithMinion extends RenderLiving<EntityBlazeMinion> {
private ResourceLocation texture = new ResourceLocation("textures/entity/blaze.png");
public RenderWraithMinion(RenderManager renderManagerIn){
super(renderManagerIn, new ModelBlaze(), 0.5F);
}
@Override
protected ResourceLocation getEntityTexture(EntityBlazeMinion entity){
return texture;
}
}
@@ -0,0 +1,118 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.construct.EntityZombieSpawner;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import org.lwjgl.opengl.GL11;
public class RenderZombieSpawner extends Render<EntityZombieSpawner> {
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/entity/zombie_spawner.png");
private static final Vec3d[] HIDDEN_BOX = WizardryUtilities.getVertices(new AxisAlignedBB(-1, 0, -1, 1, 2.5, 1));
public RenderZombieSpawner(RenderManager renderManager){
super(renderManager);
}
@Override
public void doRender(EntityZombieSpawner entity, double x, double y, double z, float yaw, float partialTicks){
GlStateManager.pushMatrix();
GlStateManager.enableBlend();
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GlStateManager.translate(x, y, z);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
// The visible bit
GlStateManager.pushMatrix();
int animationTicks = 10;
float age = entity.ticksExisted + partialTicks;
float s = age < animationTicks ? age/animationTicks : MathHelper.clamp((entity.lifetime - age) / animationTicks, 0, 1);
s = (float)Math.pow(s, 0.4); // Smooths the animation
GlStateManager.scale(s, s, s);
GlStateManager.rotate(age * 2, 0, 1, 0);
this.bindTexture(TEXTURE);
Vec3d[] vertices = WizardryUtilities.getVertices(entity.getEntityBoundingBox().offset(entity.getPositionVector().scale(-1)));
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
drawFace(buffer, vertices[0], vertices[1], vertices[3], vertices[2], 0, 0, 1, 1); // Bottom
drawFace(buffer, vertices[1], vertices[0], vertices[2], vertices[3], 0, 0, 1, 1); // Top
tessellator.draw();
GlStateManager.popMatrix();
// Hidden box
GlStateManager.disableTexture2D();
GlStateManager.colorMask(false, false, false, false); // Magically hide the zombies
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
// Outside (hides everything)
drawFaceColour(buffer, HIDDEN_BOX[6], HIDDEN_BOX[7], HIDDEN_BOX[2], HIDDEN_BOX[3], 0, 0, 0, 1); // South
drawFaceColour(buffer, HIDDEN_BOX[5], HIDDEN_BOX[6], HIDDEN_BOX[1], HIDDEN_BOX[2], 0, 0, 0, 1); // East
drawFaceColour(buffer, HIDDEN_BOX[4], HIDDEN_BOX[5], HIDDEN_BOX[0], HIDDEN_BOX[1], 0, 0, 0, 1); // North
drawFaceColour(buffer, HIDDEN_BOX[7], HIDDEN_BOX[4], HIDDEN_BOX[3], HIDDEN_BOX[0], 0, 0, 0, 1); // West
drawFaceColour(buffer, HIDDEN_BOX[5], HIDDEN_BOX[4], HIDDEN_BOX[6], HIDDEN_BOX[7], 0, 0, 0, 1); // Top
tessellator.draw();
GlStateManager.disableBlend();
GlStateManager.enableLighting();
GlStateManager.disableRescaleNormal();
GlStateManager.enableTexture2D();
GlStateManager.colorMask(true, true, true, true);
GlStateManager.popMatrix();
}
@Override
public void renderMultipass(EntityZombieSpawner entity, double x, double y, double z, float yaw, float partialTicks){
}
@Override
public boolean isMultipass(){
return false;
}
@Override
protected ResourceLocation getEntityTexture(EntityZombieSpawner entity){
return TEXTURE;
}
private static void drawFace(BufferBuilder buffer, Vec3d topLeft, Vec3d topRight, Vec3d bottomLeft, Vec3d bottomRight, float u1, float v1, float u2, float v2){
buffer.pos(topLeft.x, topLeft.y, topLeft.z).tex(u1, v1).endVertex();
buffer.pos(topRight.x, topRight.y, topRight.z).tex(u2, v1).endVertex();
buffer.pos(bottomRight.x, bottomRight.y, bottomRight.z).tex(u2, v2).endVertex();
buffer.pos(bottomLeft.x, bottomLeft.y, bottomLeft.z).tex(u1, v2).endVertex();
}
private static void drawFaceColour(BufferBuilder buffer, Vec3d topLeft, Vec3d topRight, Vec3d bottomLeft, Vec3d bottomRight, float r, float g, float b, float a){
buffer.pos(topLeft.x, topLeft.y, topLeft.z).color(r, g, b, a).endVertex();
buffer.pos(topRight.x, topRight.y, topRight.z).color(r, g, b, a).endVertex();
buffer.pos(bottomRight.x, bottomRight.y, bottomRight.z).color(r, g, b, a).endVertex();
buffer.pos(bottomLeft.x, bottomLeft.y, bottomLeft.z).color(r, g, b, a).endVertex();
}
}
@@ -0,0 +1,70 @@
package electroblob.wizardry.client.renderer.entity.layers;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.spell.Disintegration;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.entity.RenderLivingBase;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.client.event.RenderLivingEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
/**
* Layer used to render the appear/disappear animation for summoned creatures.
*
* @author Electroblob
* @since Wizardry 4.3
*/
@EventBusSubscriber
public class LayerDisintegrateAnimation<T extends EntityLivingBase> extends LayerTiledOverlay<T> {
private static final int ANIMATION_TICKS = 19; // One less than the max death time
private static final ResourceLocation[] TEXTURES = new ResourceLocation[ANIMATION_TICKS];
static {
for(int i=0; i<ANIMATION_TICKS; i++){
TEXTURES[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/disintegrate_overlay/disintegrate_overlay_" + i + ".png");
}
}
public LayerDisintegrateAnimation(RenderLivingBase<?> renderer){
super(renderer, 32, 32);
}
@Override
public boolean shouldRender(T entity, float partialTicks){
return entity.getEntityData().hasKey(Disintegration.NBT_KEY);
}
@Override
public ResourceLocation getTexture(T entity, float partialTicks){
return TEXTURES[MathHelper.clamp(entity.ticksExisted - entity.getEntityData().getInteger(Disintegration.NBT_KEY), 0, ANIMATION_TICKS - 1)];
}
@Override
public void doRenderLayer(T entity, float limbSwing, float limbSwingAmount, float partialTicks,
float ageInTicks, float netHeadYaw, float headPitch, float scale){
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
super.doRenderLayer(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
GlStateManager.enableLighting();
}
@SubscribeEvent
public static void onRenderLivingEvent(RenderLivingEvent.Pre<EntityLivingBase> event){
if(event.getEntity().getEntityData().hasKey(Disintegration.NBT_KEY)){
event.getEntity().deathTime = 0;
event.getEntity().setInvisible(true);
}
}
@SubscribeEvent
public static void onRenderLivingEvent(RenderLivingEvent.Post<EntityLivingBase> event){
if(event.getEntity().getEntityData().hasKey(Disintegration.NBT_KEY)) event.getEntity().setInvisible(false);
}
}
@@ -0,0 +1,49 @@
package electroblob.wizardry.client.renderer.entity.layers;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.block.BlockStatue;
import electroblob.wizardry.registry.WizardryPotions;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.GlStateManager.DestFactor;
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
import net.minecraft.client.renderer.entity.RenderLivingBase;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.ResourceLocation;
/**
* Layer used to render the frost texture on creatures with the frostbite effect.
*
* @author Electroblob
* @since Wizardry 1.2
*/
public class LayerFrost extends LayerTiledOverlay<EntityLivingBase> {
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/entity/frost_overlay.png");
public LayerFrost(RenderLivingBase<?> renderer){
super(renderer);
}
@Override
public boolean shouldRender(EntityLivingBase entity, float partialTicks){
return entity.isPotionActive(WizardryPotions.frost) || entity.getEntityData().getBoolean(BlockStatue.FROZEN_NBT_KEY);
}
@Override
public ResourceLocation getTexture(EntityLivingBase entity, float partialTicks){
return TEXTURE;
}
@Override
public void doRenderLayer(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks,
float ageInTicks, float netHeadYaw, float headPitch, float scale){
GlStateManager.enableBlend();
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
super.doRenderLayer(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
GlStateManager.disableBlend();
}
}
@@ -0,0 +1,61 @@
package electroblob.wizardry.client.renderer.entity.layers;
import electroblob.wizardry.block.BlockStatue;
import electroblob.wizardry.client.ClientProxy;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.GlStateManager.DestFactor;
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
import net.minecraft.client.renderer.entity.RenderLivingBase;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.ResourceLocation;
/**
* Layer used to render the stone texture on a petrified creature.
*
* @author Electroblob
* @since Wizardry 1.2
*/
// N.B. The rule here is don't restrict the type any more than necessary, so even though we *know* petrified creatures
// are always instances of EntityLiving, we don't need any methods/fields specific to EntityLiving so use ELB instead.
public class LayerStone extends LayerTiledOverlay<EntityLivingBase> {
private static final ResourceLocation TEXTURE = new ResourceLocation("textures/blocks/stone.png");
public LayerStone(RenderLivingBase<?> renderer){
super(renderer);
}
@Override
public boolean shouldRender(EntityLivingBase entity, float partialTicks){
return entity.getEntityData().getBoolean(BlockStatue.PETRIFIED_NBT_KEY);
}
@Override
public ResourceLocation getTexture(EntityLivingBase entity, float partialTicks){
ResourceLocation breakingTexture = ClientProxy.renderStatue.getBlockBreakingTexture();
return breakingTexture == null ? TEXTURE : breakingTexture;
}
// FIXME: Does not work with zombie pigmen, I have no idea why.
// I believe the issue is with the TESR actually, since LayerFrost works fine
@Override
public void doRenderLayer(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks,
float ageInTicks, float netHeadYaw, float headPitch, float scale){
// N.B. It's one or the other because this effectively gets called twice via RenderStatue
if(ClientProxy.renderStatue.getBlockBreakingTexture() != null){
GlStateManager.enableBlend();
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
super.doRenderLayer(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
GlStateManager.disableBlend();
}else{
super.doRenderLayer(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
}
}
}
@@ -0,0 +1,33 @@
package electroblob.wizardry.client.renderer.entity.layers;
import electroblob.wizardry.entity.living.EntityStrayMinion;
import net.minecraft.client.model.ModelSkeleton;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.RenderLivingBase;
import net.minecraft.client.renderer.entity.layers.LayerRenderer;
import net.minecraft.util.ResourceLocation;
/** Had to copy this entire class just because of one unnecessarily specific type parameter. The type parameter has been
* changed to {@code EntityStrayMinion} and parameter types updated accordingly. Everything else is identical. */
public class LayerStrayMinionClothing implements LayerRenderer<EntityStrayMinion> {
private static final ResourceLocation STRAY_CLOTHES_TEXTURES = new ResourceLocation("textures/entity/skeleton/stray_overlay.png");
private final RenderLivingBase<?> renderer;
private final ModelSkeleton layerModel = new ModelSkeleton(0.25F, true);
public LayerStrayMinionClothing(RenderLivingBase<?> renderer){
this.renderer = renderer;
}
public void doRenderLayer(EntityStrayMinion entity, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale){
this.layerModel.setModelAttributes(this.renderer.getMainModel());
this.layerModel.setLivingAnimations(entity, limbSwing, limbSwingAmount, partialTicks);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
this.renderer.bindTexture(STRAY_CLOTHES_TEXTURES);
this.layerModel.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale);
}
public boolean shouldCombineTextures(){
return true;
}
}
@@ -0,0 +1,88 @@
package electroblob.wizardry.client.renderer.entity.layers;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.living.ISummonedCreature;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.GlStateManager.DestFactor;
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
import net.minecraft.client.renderer.entity.RenderLivingBase;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.RenderLivingEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
/**
* Layer used to render the appear/disappear animation for summoned creatures.
*
* @author Electroblob
* @since Wizardry 4.3
*/
@EventBusSubscriber
public class LayerSummonAnimation<T extends EntityLivingBase> extends LayerTiledOverlay<T> {
private static final int ANIMATION_TICKS = 19;
private static final int HIDE_MODEL_TICKS = 9;
private static final ResourceLocation[] TEXTURES = new ResourceLocation[ANIMATION_TICKS];
static {
for(int i=0; i<ANIMATION_TICKS; i++){
TEXTURES[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/summon_overlay/summon_overlay_" + i + ".png");
}
}
public LayerSummonAnimation(RenderLivingBase<?> renderer){
super(renderer, 32, 32);
}
@Override
public boolean shouldRender(T entity, float partialTicks){
return entity instanceof ISummonedCreature && ((ISummonedCreature)entity).hasAnimation()
&& getFrameNumber(entity) < ANIMATION_TICKS;
}
@Override
public ResourceLocation getTexture(T entity, float partialTicks){
return TEXTURES[getFrameNumber(entity)];
}
private int getFrameNumber(T entity){
if(!(entity instanceof ISummonedCreature)) throw new IllegalArgumentException("Entity must be an ISummonedCreature");
return Math.min(entity.ticksExisted, Math.max(((ISummonedCreature)entity).getLifetime() - entity.ticksExisted - 1, 0));
}
@Override
public void doRenderLayer(T entity, float limbSwing, float limbSwingAmount, float partialTicks,
float ageInTicks, float netHeadYaw, float headPitch, float scale){
if(!(entity instanceof ISummonedCreature)) return;
GlStateManager.enableBlend();
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
int colour = ((ISummonedCreature)entity).getAnimationColour((float)getFrameNumber(entity) / ANIMATION_TICKS);
GlStateManager.color((colour >> 16 & 255) / 255f, (colour >> 8 & 255) / 255f, (colour & 255) / 255f);
super.doRenderLayer(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
GlStateManager.disableBlend();
}
@SubscribeEvent
public static void onRenderLivingEvent(RenderLivingEvent.Pre<EntityLivingBase> event){
if(shouldHideMainModel(event.getEntity())) event.getEntity().setInvisible(true);
}
@SubscribeEvent
public static void onRenderLivingEvent(RenderLivingEvent.Post<EntityLivingBase> event){
if(shouldHideMainModel(event.getEntity())) event.getEntity().setInvisible(false);
}
private static boolean shouldHideMainModel(EntityLivingBase entity){
return entity instanceof ISummonedCreature && ((ISummonedCreature)entity).hasAnimation()
&& (entity.ticksExisted < HIDE_MODEL_TICKS
|| ((ISummonedCreature)entity).getLifetime() - entity.ticksExisted < HIDE_MODEL_TICKS);
}
}
@@ -0,0 +1,241 @@
package electroblob.wizardry.client.renderer.entity.layers;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.model.ModelPlayer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderLivingBase;
import net.minecraft.client.renderer.entity.RenderPlayer;
import net.minecraft.client.renderer.entity.layers.LayerRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import org.lwjgl.opengl.GL11;
import java.util.function.Function;
/**
* Base class for layers that overlay a tiled texture onto the entity model. Handles dynamic tiling of the texture,
* scaling to preserve in-world pixel size (1/16 of a block), and the necessary GL state changes.
*
* @author Electroblob
* @since Wizardry 4.3
*/
public abstract class LayerTiledOverlay<T extends EntityLivingBase> implements LayerRenderer<T> {
private final RenderLivingBase<?> renderer;
private final int textureWidth;
private final int textureHeight;
/** Creates a new {@code LayerTiledOverlay} with the given renderer parameters. */
public LayerTiledOverlay(RenderLivingBase<?> renderer, int textureWidth, int textureHeight){
this.textureWidth = textureWidth;
this.textureHeight = textureHeight;
this.renderer = renderer;
}
/** Creates a new {@code LayerTiledOverlay} with the given renderer. Texture width and height default to 16. */
public LayerTiledOverlay(RenderLivingBase<?> renderer){
this(renderer, 16, 16);
}
/**
* Returns true if this layer should be rendered for the given entity, false if not.
* @param entity The entity being rendered
* @param partialTicks The current partial tick time
* @return True if this layer should be rendered, false if not.
*/
public abstract boolean shouldRender(T entity, float partialTicks);
/**
* Returns the texture to use for the overlay.
* @param entity The entity being rendered
* @param partialTicks The current partial tick time
* @return A {@link ResourceLocation} specifying the texture to use.
*/
public abstract ResourceLocation getTexture(T entity, float partialTicks);
/**
* Returns the model to use for the overlay. Defaults to the renderer's main model.
* @param entity The entity being rendered
* @param partialTicks The current partial tick time
* @return The model to use. Swapping different models in dynamically is fine, but don't create new ones each time.
*/
public ModelBase getModel(T entity, float partialTicks){
return renderer.getMainModel();
}
/**
* Returns whether to render the second layer of mob/player skins (which is not an <i>actual</i> render layer, but
* part of the model) as part of this layer. Defaults to false.
* @param entity The entity being rendered
* @param partialTicks The current partial tick time
* @return True to render any non-hidden second layer boxes, false to always hide them from this layer.
*/
public boolean renderSecondLayer(T entity, float partialTicks){
return false; // Normally it looks kind of weird because second layers typically have holes in them
}
@Override
public void doRenderLayer(T entity, float limbSwing, float limbSwingAmount, float partialTicks,
float ageInTicks, float netHeadYaw, float headPitch, float scale){
if(shouldRender(entity, partialTicks)){
this.renderer.bindTexture(getTexture(entity, partialTicks));
this.renderEntityModel(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
}
}
@Override
public boolean shouldCombineTextures(){
return false;
}
protected static int getBlockBrightnessForEntity(Entity entity){
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(MathHelper.floor(entity.posX), 0,
MathHelper.floor(entity.posZ));
if(entity.world.isBlockLoaded(pos)){
pos.setY(MathHelper.floor(entity.posY + (double)entity.getEyeHeight()));
return entity.world.getCombinedLight(pos, 0);
}else{
return 0;
}
}
private void renderEntityModel(T entity, float limbSwing, float limbSwingAmount, float partialTicks,
float ageInTicks, float netHeadYaw, float headPitch, float scale){
GlStateManager.pushMatrix();
// Enables texture tiling (Also used for guardian beam, beacon beam and ender crystal beam, amongst others)
GlStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GlStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GlStateManager.depthMask(true); // Some entities set depth mask to false (i.e. no sorting of faces by depth)
// In particular, LayerSpiderEyes sets it to false when the spider is invisible, for some reason.
// Changes the scale at which the texture is applied to the model. See LayerCreeper for a similar example,
// but with translation instead of scaling.
// You can do all sorts of fun stuff with this, just by applying transformations in the 2D texture space.
GlStateManager.matrixMode(GL11.GL_TEXTURE); // Switch to the 2D texture space
GlStateManager.loadIdentity();
ModelBase model = getModel(entity, partialTicks);
// Calculate the scaling required in each direction
double scaleX = 1, scaleY = 1;
// It's more logical to use the model's texture size, but some classes don't bother setting it properly
// (e.g. ModelVillager), so to get the correct dimensions I'm getting them from the first box instead.
if(model.boxList != null && model.boxList.get(0) != null){
scaleX = (double)model.boxList.get(0).textureWidth / textureWidth;
scaleY = (double)model.boxList.get(0).textureHeight / textureHeight;
}else{ // Fallback to model fields; should never be needed
scaleX = (double)model.textureWidth / textureWidth;
scaleY = (double)model.textureHeight / textureHeight;
}
GlStateManager.scale(scaleX, scaleY, 1);
GlStateManager.matrixMode(GL11.GL_MODELVIEW); // Switch back to the 3D model space
boolean headWearHidden = false;
boolean bodyWearHidden = false;
boolean leftArmWearHidden = false;
boolean rightArmWearHidden = false;
boolean leftLegWearHidden = false;
boolean rightLegWearHidden = false;
if(!renderSecondLayer(entity, partialTicks)){
// Hide the hat layer for bipeds, and all the other body part overlays for players
if(model instanceof ModelBiped){
headWearHidden = ((ModelBiped)model).bipedHeadwear.isHidden;
((ModelBiped)model).bipedHeadwear.isHidden = true;
}
if(model instanceof ModelPlayer){
bodyWearHidden = ((ModelPlayer)model).bipedBodyWear.isHidden;
leftArmWearHidden = ((ModelPlayer)model).bipedLeftArmwear.isHidden;
rightArmWearHidden = ((ModelPlayer)model).bipedRightArmwear.isHidden;
leftLegWearHidden = ((ModelPlayer)model).bipedLeftLegwear.isHidden;
rightLegWearHidden = ((ModelPlayer)model).bipedRightLegwear.isHidden;
((ModelPlayer)model).bipedBodyWear.isHidden = true;
((ModelPlayer)model).bipedLeftArmwear.isHidden = true;
((ModelPlayer)model).bipedRightArmwear.isHidden = true;
((ModelPlayer)model).bipedLeftLegwear.isHidden = true;
((ModelPlayer)model).bipedRightLegwear.isHidden = true;
}
}
// Actually render the model
model.setLivingAnimations(entity, limbSwing, limbSwingAmount, partialTicks);
model.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale);
if(!renderSecondLayer(entity, partialTicks)){
// Reset the hidden status of everything to how it was before
if(model instanceof ModelBiped){
((ModelBiped)model).bipedHeadwear.isHidden = headWearHidden;
}
if(model instanceof ModelPlayer){
((ModelPlayer)model).bipedBodyWear.isHidden = bodyWearHidden;
((ModelPlayer)model).bipedLeftArmwear.isHidden = leftArmWearHidden;
((ModelPlayer)model).bipedRightArmwear.isHidden = rightArmWearHidden;
((ModelPlayer)model).bipedLeftLegwear.isHidden = leftLegWearHidden;
((ModelPlayer)model).bipedRightLegwear.isHidden = rightLegWearHidden;
}
}
// Undo the texture scaling
GlStateManager.matrixMode(GL11.GL_TEXTURE);
GlStateManager.loadIdentity();
GlStateManager.matrixMode(GL11.GL_MODELVIEW);
GlStateManager.popMatrix();
}
/**
* Helper method to initialise a layer renderer for all applicable renderers. This method will work for any layer
* renderer, not just instances of {@code LayerTiledOverlay} (it is stored here purely for convenience).
* @param entityType The class of entity to initialise this layer renderer for (including subclasses)
* @param layerFactory A function that creates a layer for a given renderer, usually a constructor reference
* @param <T> The type of entity this layer renderer is applicable for
*/
@SuppressWarnings("unchecked")
public static <T extends EntityLivingBase> void initialiseLayers(Class<T> entityType, Function<RenderLivingBase<T>, LayerRenderer<? extends T>> layerFactory){
for(Class<? extends Entity> c : Minecraft.getMinecraft().getRenderManager().entityRenderMap.keySet()){
if(entityType.isAssignableFrom(c)){
Render<T> renderer = Minecraft.getMinecraft().getRenderManager().getEntityClassRenderObject(c);
if(renderer instanceof RenderLivingBase<?>){ // Should always be true
// For some reason IntelliJ is quite happy with this cast, even without suppress warnings
// Instinct suggests Java shouldn't be happy casting to RenderLivingBase<T> but somehow it works
((RenderLivingBase<T>)renderer).addLayer(layerFactory.apply((RenderLivingBase<T>)renderer));
}
}
}
// Players have a separate renderer map
if(entityType.isAssignableFrom(EntityPlayer.class)){
for(RenderPlayer renderer : Minecraft.getMinecraft().getRenderManager().getSkinMap().values()){
renderer.addLayer(layerFactory.apply((RenderLivingBase<T>)renderer)); // This does need suppress warnings
}
}
}
/**
* Helper method to initialise a layer renderer for all living entity renderers. This is a shorthand version of
* {@link LayerTiledOverlay#initialiseLayers(Class, Function)}.
* @param layerFactory A function that creates a layer for a given renderer, usually a constructor reference
*/
public static void initialiseLayers(Function<RenderLivingBase<EntityLivingBase>, LayerRenderer<? extends EntityLivingBase>> layerFactory){
initialiseLayers(EntityLivingBase.class, layerFactory);
}
}