/**
* 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.core.entity;
import cn.lambdalib.util.entityx.EntityAdvanced;
import cn.lambdalib.util.entityx.EntityCallback;
import cn.lambdalib.util.generic.RandUtils;
import cn.lambdalib.util.helper.GameTimer;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
/**
* @author WeAthFolD
*/
@SideOnly(Side.CLIENT)
public class EntityRayBase extends EntityAdvanced implements IRay {
EntityPlayer spawner;
public int life = 30;
public long blendInTime = 100;
public long blendOutTime = 300;
public long widthShrinkTime = 300;
public double length = 15.0;
public double widthWiggleRadius = 0.1;
public double maxWiggleSpeed = 0.4;
public double widthWiggle = 0.0;
public double glowWiggleRadius = 0.1;
public double maxGlowWiggleSpeed = 0.4;
public double glowWiggle = 0.0;
public boolean viewOptimize = true;
long lastFrame = 0;
long creationTime;
/**
* This just link the ray to a player. You still have to setup the view direction based on the ray type.
*/
public EntityRayBase(EntityPlayer player) {
this(player.worldObj);
spawner = player;
}
public EntityRayBase(World world) {
super(world);
creationTime = GameTimer.getTime();
ignoreFrustumCheck = true;
}
public void setFromTo(Vec3 from, Vec3 to) {
setFromTo(from.xCoord, from.yCoord, from.zCoord, to.xCoord, to.yCoord, to.zCoord);
}
public void setFromTo(double x0, double y0, double z0, double x1, double y1, double z1) {
setPosition(x0, y0, z0);
double dx = x1 - x0, dy = y1 - y0, dz = z1 - z0;
double dxzsq = dx * dx + dz * dz;
rotationYaw = (float) (-Math.atan2(dx, dz) * 180 / Math.PI);
rotationPitch = (float) (-Math.atan2(dy, Math.sqrt(dxzsq)) * 180 / Math.PI);
length = Math.sqrt(dxzsq + dy * dy);
}
@Override
protected void onFirstUpdate() {
executeAfter(new EntityCallback() {
@Override
public void execute(Entity target) {
setDead();
}
}, life);
}
protected long getDeltaTime() {
return GameTimer.getTime() - creationTime;
}
@Override
public Vec3 getPosition() {
return Vec3.createVectorHelper(posX, posY, posZ);
}
@Override
public double getLength() {
long dt = GameTimer.getTime() - creationTime;
return (dt < blendInTime ? (double)dt / blendInTime : 1) * length;
}
@Override
public boolean shouldRenderInPass(int pass) {
return pass == 1;
}
@Override
protected void readEntityFromNBT(NBTTagCompound tag) {
posX = tag.getDouble("x");
posY = tag.getDouble("y");
posZ = tag.getDouble("z");
}
@Override
protected void writeEntityToNBT(NBTTagCompound tag) {
tag.setDouble("x", posX);
tag.setDouble("y", posY);
tag.setDouble("z", posZ);
}
public long getLifeMS() {
return life * 50;
}
//TODO Add glow texture alpha wiggle
@Override
public double getAlpha() {
long dt = getDeltaTime();
long lifeMS = getLifeMS();
return dt > lifeMS - blendOutTime ? 1 - (double) (dt + blendOutTime - lifeMS) / blendOutTime : 1.0;
}
@Override
public double getWidth() {
long dt = getDeltaTime();
long lifeMS = getLifeMS();
return widthWiggle +
(dt > lifeMS - widthShrinkTime ? 1 - (double) (dt + widthShrinkTime - lifeMS) / widthShrinkTime : 1.0);
}
@Override
public boolean needsViewOptimize() {
return viewOptimize;
}
@Override
public double getStartFix() {
return 0.0;
}
@Override
public void onRenderTick() {
long time = GameTimer.getTime();
if(lastFrame != 0) {
long dt = time - lastFrame;
widthWiggle += dt * RandUtils.ranged(-maxWiggleSpeed, maxWiggleSpeed) / 1000.0;
if(widthWiggle > widthWiggleRadius)
widthWiggle = widthWiggleRadius;
if(widthWiggle < 0)
widthWiggle = 0;
glowWiggle += dt * RandUtils.ranged(-maxGlowWiggleSpeed, maxGlowWiggleSpeed) / 1000.0;
if(glowWiggle > glowWiggleRadius)
glowWiggle = glowWiggleRadius;
if(glowWiggle < 0)
glowWiggle = 0;
}
lastFrame = GameTimer.getTime();
}
@Override
public double getGlowAlpha() {
long dt = GameTimer.getTime() - creationTime;
long lifeMS = getLifeMS();
return (1 - glowWiggleRadius + glowWiggle) * getAlpha();
}
@Override
public EntityPlayer getPlayer() {
return spawner;
}
}