/**
* Copyright (c) Lambda Innovation, 2013-2016
* This file is part of the AcademyCraft mod.
* https://github.com/LambdaInnovation/AcademyCraft
* Licensed under GPLv3, see project root for more information.
*/
package cn.academy.vanilla.electromaster.entity;
import cn.academy.core.client.IPointFactory;
import cn.academy.core.client.render.CubePointFactory;
import cn.academy.vanilla.electromaster.client.effect.ArcFactory;
import cn.academy.vanilla.electromaster.client.effect.ArcFactory.Arc;
import cn.academy.vanilla.electromaster.client.effect.SubArcHandler;
import cn.lambdalib.annoreg.core.Registrant;
import cn.lambdalib.annoreg.mc.RegEntity;
import cn.lambdalib.util.entityx.EntityAdvanced;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import org.lwjgl.opengl.GL11;
/**
* Spawn a surround arc effect around the specific entity or block.
* @author WeAthFolD
*/
@Registrant
@SideOnly(Side.CLIENT)
@RegEntity(clientOnly = true)
@RegEntity.HasRender
public class EntitySurroundArc extends EntityAdvanced {
static final int TEMPLATES = 15;
static {
ArcFactory factory = new ArcFactory();
factory.widthShrink = 0.9;
factory.maxOffset = 0.8;
factory.passes = 3;
factory.width = 0.2;
factory.branchFactor = 0.7;
ArcType.THIN.templates = factory.generateList(10, 1.5, 2);
factory.width = 0.3;
ArcType.NORMAL.templates = factory.generateList(10, 3, 4);
factory.passes = 3;
factory.width = 0.35;
factory.maxOffset = 1.2;
factory.branchFactor = 0.45;
ArcType.BOLD.templates = factory.generateList(10, 3.5, 4.5);
}
public enum ArcType {
THIN(4), NORMAL(6), BOLD(5);
public Arc[] templates;
public int count;
ArcType(int _count) {
count = _count;
}
}
@RegEntity.Render
public static Renderer renderer;
private ArcType arcType = ArcType.BOLD;
private final PosObject pos;
public boolean draw = true;
public int life = 100;
SubArcHandler arcHandler;
IPointFactory pointFactory;
public EntitySurroundArc(Entity follow) {
this(follow, 1.3);
}
public EntitySurroundArc(Entity follow, double sizeMultiplyer) {
super(follow.worldObj);
pos = new EntityPos(follow);
pointFactory = new CubePointFactory(
follow.width * sizeMultiplyer,
follow.height * sizeMultiplyer,
follow.width * sizeMultiplyer).setCentered(true);
}
public EntitySurroundArc(World world, double x, double y, double z, double wl, double h) {
super(world);
pos = new ConstPos(x, y, z);
pointFactory = new CubePointFactory(wl, h, wl).setCentered(true);
}
public void updatePos(double x, double y, double z) {
pos.x = x;
pos.y = y;
pos.z = z;
}
public EntitySurroundArc setArcType(ArcType type) {
arcType = type;
return this;
}
public EntitySurroundArc setLife(int life) {
this.life = life;
return this;
}
@Override
public void entityInit() {
ignoreFrustumCheck = true;
}
@Override
public boolean shouldRenderInPass(int pass) {
return pass == 1;
}
@Override
public void onFirstUpdate() {
// Create the arcs!
arcHandler = new SubArcHandler(arcType.templates);
arcHandler.frameRate = 0.6;
arcHandler.switchRate = 0.7;
doGenerate();
}
/**
* Do the arc generation.
*/
protected void doGenerate() {
for(int i = 0; i < arcType.count; ++i) {
double yaw = rand.nextDouble() * Math.PI * 2;
double pitch = rand.nextDouble() * Math.PI;
double y = Math.sin(pitch),
zz = Math.sqrt(1 - y * y),
x = zz * Math.sin(yaw),
z = zz * Math.cos(yaw);
arcHandler.generateAt(pointFactory.next());
}
}
@Override
public void onUpdate() {
super.onUpdate();
if(arcHandler.isEmpty())
doGenerate();
arcHandler.tick();
pos.tick();
setPosition(pos.x, pos.y, pos.z);
rotationYaw = pos.yaw;
rotationPitch = pos.pitch;
if(ticksExisted == life)
setDead();
}
@Override
protected void readEntityFromNBT(NBTTagCompound tag) {
setDead();
}
@Override
protected void writeEntityToNBT(NBTTagCompound tag) {}
private abstract class PosObject {
double x, y, z;
float yaw, pitch;
void tick() {}
}
public static class Renderer extends Render {
@Override
public void doRender(Entity entity, double x,
double y, double z, float a,
float b) {
EntitySurroundArc esa = (EntitySurroundArc) entity;
if(esa.draw && esa.arcHandler != null) {
GL11.glPushMatrix();
GL11.glTranslated(x, y, z);
GL11.glRotatef(-esa.rotationYaw, 0, 1, 0);
esa.arcHandler.drawAll();
GL11.glPopMatrix();
}
}
@Override
protected ResourceLocation getEntityTexture(Entity entity) {
return null;
}
}
private class EntityPos extends PosObject {
final Entity entity;
final boolean isPlayer;
public EntityPos(Entity e) {
entity = e;
isPlayer = e instanceof EntityPlayer && e.equals(Minecraft.getMinecraft().thePlayer);
}
@Override
void tick() {
x = entity.posX;
y = isPlayer ? entity.posY - 1.6 : entity.posY;
z = entity.posZ;
yaw = entity instanceof EntityLivingBase ? ((EntityLivingBase)entity).rotationYawHead : entity.rotationYaw;
pitch = entity.rotationPitch;
}
}
private class ConstPos extends PosObject {
public ConstPos(double _x, double _y, double _z) {
x = _x;
y = _y;
z = _z;
}
}
}