Added particle bunch entity with rendering (wip)

This commit is contained in:
LemADEC 2017-02-09 21:38:35 +01:00
parent 22e5c3efb6
commit aa3280ff31
6 changed files with 287 additions and 10 deletions

View file

@ -3,6 +3,7 @@ package cr0s.warpdrive;
import com.mojang.authlib.GameProfile;
import cpw.mods.fml.common.registry.EntityRegistry;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.entity.EntityParticleBunch;
import cr0s.warpdrive.render.EntityCamera;
import cr0s.warpdrive.world.EntitySphereGen;
import cr0s.warpdrive.world.EntityStarCore;
@ -21,13 +22,18 @@ import net.minecraftforge.event.world.BlockEvent;
import java.lang.ref.WeakReference;
import java.util.WeakHashMap;
public class CommonProxy {
public abstract class CommonProxy {
private static final WeakHashMap<GameProfile, WeakReference<EntityPlayer>> fakePlayers = new WeakHashMap<>(100);
void registerEntities() {
EntityRegistry.registerModEntity(EntitySphereGen.class, "EntitySphereGenerator", WarpDriveConfig.G_ENTITY_SPHERE_GENERATOR_ID, WarpDrive.instance, 200, 1, false);
EntityRegistry.registerModEntity(EntityStarCore.class , "EntityStarCore" , WarpDriveConfig.G_ENTITY_STAR_CORE_ID , WarpDrive.instance, 300, 1, false);
EntityRegistry.registerModEntity(EntityCamera.class , "EntityCamera" , WarpDriveConfig.G_ENTITY_CAMERA_ID , WarpDrive.instance, 300, 1, false);
EntityRegistry.registerModEntity(EntitySphereGen.class , "EntitySphereGenerator", WarpDriveConfig.G_ENTITY_SPHERE_GENERATOR_ID, WarpDrive.instance, 200, 1, false);
EntityRegistry.registerModEntity(EntityStarCore.class , "EntityStarCore" , WarpDriveConfig.G_ENTITY_STAR_CORE_ID , WarpDrive.instance, 300, 1, false);
EntityRegistry.registerModEntity(EntityCamera.class , "EntityCamera" , WarpDriveConfig.G_ENTITY_CAMERA_ID , WarpDrive.instance, 300, 1, false);
EntityRegistry.registerModEntity(EntityParticleBunch.class, "EntityParticleBunch" , WarpDriveConfig.G_ENTITY_PARTICLE_BUNCH_ID , WarpDrive.instance, 300, 1, false);
}
public void registerRendering() {
// client side only
}
private EntityPlayer getFakePlayer(EntityPlayer entityPlayer, WorldServer world, int x, int y, int z) {

View file

@ -16,11 +16,11 @@ public class ParticleRegistry {
private static BiMap<String, Particle> particles = HashBiMap.create();
public static final Particle ION = new Particle("ion") { }.setColor(0xE5FF54).setRarity(EnumRarity.common);
public static final Particle PROTON = new Particle("proton") { }.setColor(0xE5FF54).setRarity(EnumRarity.common);
public static final Particle ANTIMATTER = new Particle("antimatter") { }.setColor(0x1C3CAF).setRarity(EnumRarity.uncommon);
public static final Particle STRANGE_MATTER = new Particle("strange_matter") { }.setColor(0xE2414C).setRarity(EnumRarity.rare);
// public static final Particle TACHYONS = new Particle("tachyons") { }.setColor(0xE5FF54).setRarity(EnumRarity.epic);
public static final Particle ION = new Particle("ion") { }.setColor(0xE5FF54).setRarity(EnumRarity.common).setColorIndex(0);
public static final Particle PROTON = new Particle("proton") { }.setColor(0xE5FF54).setRarity(EnumRarity.common).setColorIndex(1);
public static final Particle ANTIMATTER = new Particle("antimatter") { }.setColor(0x1C3CAF).setRarity(EnumRarity.uncommon).setColorIndex(2);
public static final Particle STRANGE_MATTER = new Particle("strange_matter") { }.setColor(0xE2414C).setRarity(EnumRarity.rare).setColorIndex(3);
// public static final Particle TACHYONS = new Particle("tachyons") { }.setColor(0xE5FF54).setRarity(EnumRarity.epic).setColorIndex(4);
static {
registerParticle(ION);

View file

@ -1,7 +1,15 @@
package cr0s.warpdrive.client;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cr0s.warpdrive.CommonProxy;
import cr0s.warpdrive.entity.EntityParticleBunch;
import cr0s.warpdrive.render.RenderEntityParticleBunch;
public class ClientProxy extends CommonProxy {
@Override
public void registerRendering() {
super.registerRendering();
RenderingRegistry.registerEntityRenderingHandler(EntityParticleBunch.class, new RenderEntityParticleBunch());
}
}

View file

@ -78,6 +78,7 @@ public class WarpDriveConfig {
public static int G_ENTITY_SPHERE_GENERATOR_ID = 241;
public static int G_ENTITY_STAR_CORE_ID = 242;
public static int G_ENTITY_CAMERA_ID = 243;
public static int G_ENTITY_PARTICLE_BUNCH_ID = 244;
public static final int LUA_SCRIPTS_NONE = 0;
public static final int LUA_SCRIPTS_TEMPLATES = 1;
@ -362,6 +363,8 @@ public class WarpDriveConfig {
config.get("general", "entity_star_core_id", G_ENTITY_STAR_CORE_ID, "Entity star core ID").getInt());
G_ENTITY_CAMERA_ID = clamp(Integer.MIN_VALUE, Integer.MAX_VALUE,
config.get("general", "entity_camera_id", G_ENTITY_CAMERA_ID, "Entity camera ID").getInt());
G_ENTITY_PARTICLE_BUNCH_ID = clamp(Integer.MIN_VALUE, Integer.MAX_VALUE,
config.get("general", "entity_particle_bunch_id", G_ENTITY_PARTICLE_BUNCH_ID, "Entity particle bunch ID").getInt());
G_LUA_SCRIPTS = clamp(0, 2,
config.get("general", "lua_scripts", G_LUA_SCRIPTS,

View file

@ -0,0 +1,125 @@
package cr0s.warpdrive.entity;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.Vector3;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
/*
* Created by LemADEC on 02/02/2017.
*/
public class EntityParticleBunch extends Entity {
// persistent properties
public double energy = 0.0D;
public Vector3 vectorNextPosition = new Vector3(0.0D, 0.0D, 0.0D);
public Vector3 vectorTurningPoint = null;
// computed properties
private int lastUpdateTicks = 0;
private static final int UPDATE_TICKS_TIMEOUT = 20;
public EntityParticleBunch(World world) {
super(world);
if (WarpDriveConfig.LOGGING_ACCELERATOR) {
WarpDrive.logger.info(this + " created in dimension '" + worldObj.getWorldInfo().getWorldName() + "'");
}
}
public EntityParticleBunch(World world, int x, int y, int z) {
super(world);
this.posX = x + 0.5D;
this.posY = y + 0.5D;
this.posZ = z + 0.5D;
if (WarpDriveConfig.LOGGING_ACCELERATOR) {
WarpDrive.logger.info(this + " created");
}
}
// override to skip the block bounding override on client side
@Override
public void setPositionAndRotation2(double x, double y, double z, float yaw, float pitch, int p_70056_9_) {
// super.setPositionAndRotation2(x, y, z, yaw, pitch, p_70056_9_);
this.setPosition(x, y, z);
this.setRotation(yaw, pitch);
}
@Override
public boolean isEntityInvulnerable() {
return true;
}
public void onRefreshFromSimulation(final double newEnergy, Vector3 vectorNewPosition, Vector3 vectorNewTurningPoint) {
setPosition(vectorNextPosition.x, vectorNextPosition.y, vectorNextPosition.z);
energy = newEnergy;
vectorNextPosition = vectorNewPosition;
vectorTurningPoint = vectorNewTurningPoint;
lastUpdateTicks = 0;
}
@Override
public void onUpdate() {
if (worldObj.isRemote) {
return;
}
lastUpdateTicks++;
if (lastUpdateTicks > UPDATE_TICKS_TIMEOUT) {
setDead();
}
}
@Override
protected void entityInit() {
// no data watcher
// entity size is used by vanilla to define render distance, so we force to a high value and adjust in render itself
setSize(2.0F, 2.0F);
yOffset = 2.0F;
noClip = true;
}
@Override
public void setDead() {
super.setDead();
if (WarpDriveConfig.LOGGING_ACCELERATOR) {
WarpDrive.logger.info(this + " dead");
}
}
@Override
public void onChunkLoad() {
super.onChunkLoad();
// we're not supposed to reload this entity from a save
setDead();
}
@Override
protected void readEntityFromNBT(NBTTagCompound nbtTagCompound) {
energy = nbtTagCompound.getInteger("energy");
vectorNextPosition = Vector3.createFromNBT(nbtTagCompound.getCompoundTag("nextPosition"));
if (nbtTagCompound.hasKey("turningPoint")) {
vectorTurningPoint = Vector3.createFromNBT(nbtTagCompound.getCompoundTag("turningPoint"));
}
}
@Override
protected void writeEntityToNBT(NBTTagCompound nbtTagCompound) {
nbtTagCompound.setDouble("energy", energy);
nbtTagCompound.setTag("nextPosition", vectorNextPosition.writeToNBT(new NBTTagCompound()));
if (vectorTurningPoint != null) {
nbtTagCompound.setTag("turningPoint", vectorTurningPoint.writeToNBT(new NBTTagCompound()));
}
}
@Override
public String toString() {
return String.format("%s/%d @ \'%s\' %.2f %.2f %.2f",
getClass().getSimpleName(),
getEntityId(),
worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName(),
posX, posY, posZ);
}
}

View file

@ -0,0 +1,135 @@
package cr0s.warpdrive.render;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import cr0s.warpdrive.entity.EntityParticleBunch;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderEntity;
import net.minecraft.entity.Entity;
import org.lwjgl.opengl.GL11;
import java.util.Random;
@SideOnly(Side.CLIENT)
public class RenderEntityParticleBunch extends RenderEntity {
@Override
public void doRender(Entity entity, double x, double y, double z, float rotation, float partialTick) {
if (entity instanceof EntityParticleBunch) {
doRender((EntityParticleBunch) entity, x, y, z, rotation, partialTick);
}
}
@Override
public void doRenderShadowAndFire(Entity entity, double x, double y, double z, float rotation, float partialTick) {
// super.doRenderShadowAndFire(entity, x, y, z, rotation, partialTick);
}
public void doRender(EntityParticleBunch entityParticleBunch, double x, double y, double z, float rotation, float partialTick) {
// adjust render distance
final int maxRenderDistanceSquared;
if (Minecraft.getMinecraft().gameSettings.fancyGraphics) {
maxRenderDistanceSquared = 128 * 128;
} else {
maxRenderDistanceSquared = 20 * 20;
}
if ((x * x + y * y + z * z) > maxRenderDistanceSquared) {
return;
}
// translate
GL11.glPushMatrix();
GL11.glTranslatef((float) x, (float) y, (float) z);
// compute parameters
final float energy = (float) entityParticleBunch.energy;
final float size = Math.min(Math.max(energy / 50000F, 0.01F), 0.07F);
final int rayCount_base = 45;
renderStar(entityParticleBunch.ticksExisted + partialTick, entityParticleBunch.getEntityId(), rayCount_base,
1.0F, 0.2F, 0.5F, 0.5F, 1.0F, 0.2F, size, size, size);
// restore
GL11.glPopMatrix();
}
// Loosely based on ender dragon death effect
private static void renderStar(final float ticksExisted, final long seed, final int rayCount_base,
final float redIn, final float greenIn, final float blueIn,
final float redOut, final float greenOut, final float blueOut,
final float scaleX, final float scaleY, final float scaleZ) {
Random random = new Random(seed);
// compute rotation cycle
final int tickRotationPeriod = 220 + 2 * random.nextInt(30);
int tickRotation = (int) (ticksExisted % tickRotationPeriod);
if (tickRotation >= tickRotationPeriod / 2) {
tickRotation = tickRotationPeriod - tickRotation - 1;
}
final float cycleRotation = 2 * tickRotation / (float) tickRotationPeriod;
// compute boost pulsation cycle
final int tickBoostPeriod = 15 + 2 * random.nextInt(10);
int tickBoost = (int) (ticksExisted % tickBoostPeriod);
if (tickBoost >= tickBoostPeriod / 2) {
tickBoost = tickBoostPeriod - tickBoost - 1;
}
final float cycleBoost = 2 * tickBoost / (float) tickBoostPeriod;
float boost = 0.0F;
if (cycleBoost > 0.7F) {
boost = (cycleBoost - 0.6F) / 0.4F;
}
// compute number of rays
// final int rayCount = 45 + (int) ((cycleRotation + cycleRotation * cycleRotation) * 15.0F);
final int rayCount = rayCount_base + random.nextInt(10);
// drawing preparation
Tessellator tessellator = Tessellator.instance;
RenderHelper.disableStandardItemLighting();
GL11.glPushAttrib(GL11.GL_LIGHTING_BIT | GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glShadeModel(GL11.GL_SMOOTH);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
GL11.glDisable(GL11.GL_ALPHA_TEST);
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glDepthMask(false);
GL11.glPushMatrix();
GL11.glScalef(scaleX, scaleY, scaleZ);
for (int i = 0; i < rayCount; i++) {
GL11.glRotatef(random.nextFloat() * 360.0F, 1.0F, 0.0F, 0.0F);
GL11.glRotatef(random.nextFloat() * 360.0F, 0.0F, 1.0F, 0.0F);
GL11.glRotatef(random.nextFloat() * 360.0F, 0.0F, 0.0F, 1.0F);
GL11.glRotatef(random.nextFloat() * 360.0F, 1.0F, 0.0F, 0.0F);
GL11.glRotatef(random.nextFloat() * 360.0F, 0.0F, 1.0F, 0.0F);
GL11.glRotatef(random.nextFloat() * 360.0F + cycleRotation * 90F, 0.0F, 0.0F, 1.0F);
tessellator.startDrawing(6);
float rayLength = random.nextFloat() * 20.0F + 5.0F + boost * 10.0F;
float rayWidth = random.nextFloat() * 2.0F + 1.0F + boost * 2.0F;
tessellator.setColorRGBA_F(redIn, greenIn, blueIn, (int) (255F * (1.0F - boost)));
tessellator.addVertex(0.0D , 0.0D, 0.0D);
tessellator.setColorRGBA_F(redOut, greenOut, blueOut, 0);
tessellator.addVertex(-0.866D * rayWidth, rayLength, -0.5D * rayWidth);
tessellator.addVertex( 0.866D * rayWidth, rayLength, -0.5D * rayWidth);
tessellator.addVertex( 0.000D , rayLength, 1.0D * rayWidth);
tessellator.addVertex(-0.866D * rayWidth, rayLength, -0.5D * rayWidth);
tessellator.draw();
}
// drawing closure
GL11.glPopMatrix();
GL11.glDepthMask(true);
GL11.glDisable(GL11.GL_CULL_FACE);
GL11.glDisable(GL11.GL_BLEND);
GL11.glShadeModel(GL11.GL_FLAT);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_ALPHA_TEST);
GL11.glPopAttrib();
RenderHelper.enableStandardItemLighting();
}
}