Redo rendering of the molecular assembler and it's animation
This commit is contained in:
@@ -7,18 +7,10 @@ import java.util.function.Consumer;
|
|||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityClassification;
|
import net.minecraft.entity.EntityClassification;
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
|
||||||
import net.minecraftforge.fml.client.registry.RenderingRegistry;
|
|
||||||
|
|
||||||
import appeng.api.features.AEFeature;
|
import appeng.api.features.AEFeature;
|
||||||
import appeng.bootstrap.components.IClientSetupComponent;
|
|
||||||
import appeng.bootstrap.components.IEntityRegistrationComponent;
|
import appeng.bootstrap.components.IEntityRegistrationComponent;
|
||||||
import appeng.core.AppEng;
|
import appeng.core.AppEng;
|
||||||
import appeng.entity.EntityFloatingItem;
|
|
||||||
import appeng.entity.EntityTinyTNTPrimed;
|
|
||||||
import appeng.entity.RenderFloatingItem;
|
|
||||||
import appeng.entity.RenderTinyTNTPrimed;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to register a custom Entity with Minecraft.
|
* Helper to register a custom Entity with Minecraft.
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ import appeng.client.render.effects.*;
|
|||||||
import appeng.core.AEConfig;
|
import appeng.core.AEConfig;
|
||||||
import appeng.core.AppEng;
|
import appeng.core.AppEng;
|
||||||
import appeng.core.sync.network.NetworkHandler;
|
import appeng.core.sync.network.NetworkHandler;
|
||||||
import appeng.core.sync.packets.PacketAssemblerAnimation;
|
|
||||||
import appeng.core.sync.packets.PacketValueConfig;
|
import appeng.core.sync.packets.PacketValueConfig;
|
||||||
import appeng.helpers.IMouseWheelItem;
|
import appeng.helpers.IMouseWheelItem;
|
||||||
import appeng.server.ServerHelper;
|
import appeng.server.ServerHelper;
|
||||||
@@ -94,15 +93,9 @@ public class ClientHelper extends ServerHelper {
|
|||||||
final double posZ, final Object o) {
|
final double posZ, final Object o) {
|
||||||
if (AEConfig.instance().isEnableEffects()) {
|
if (AEConfig.instance().isEnableEffects()) {
|
||||||
switch (effect) {
|
switch (effect) {
|
||||||
case Assembler:
|
|
||||||
this.spawnAssembler(world, posX, posY, posZ, o);
|
|
||||||
return;
|
|
||||||
case Vibrant:
|
case Vibrant:
|
||||||
this.spawnVibrant(world, posX, posY, posZ);
|
this.spawnVibrant(world, posX, posY, posZ);
|
||||||
return;
|
return;
|
||||||
case Crafting:
|
|
||||||
this.spawnCrafting(world, posX, posY, posZ);
|
|
||||||
return;
|
|
||||||
case Energy:
|
case Energy:
|
||||||
this.spawnEnergy(world, posX, posY, posZ);
|
this.spawnEnergy(world, posX, posY, posZ);
|
||||||
return;
|
return;
|
||||||
@@ -183,18 +176,6 @@ public class ClientHelper extends ServerHelper {
|
|||||||
// FIXME }
|
// FIXME }
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: double check all of these particle spawns, also move any of these that
|
|
||||||
// are triggered as part of a packet to the vanilla way of spawning particles
|
|
||||||
// from the server directly
|
|
||||||
private void spawnAssembler(final World world, final double posX, final double posY, final double posZ,
|
|
||||||
final Object o) {
|
|
||||||
final PacketAssemblerAnimation paa = (PacketAssemblerAnimation) o;
|
|
||||||
|
|
||||||
final AssemblerFX fx = new AssemblerFX(world, posX, posY, posZ, 0.0D, 0.0D, 0.0D, paa.rate,
|
|
||||||
paa.is.asItemStackRepresentation());
|
|
||||||
Minecraft.getInstance().particles.addEffect(fx);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void spawnVibrant(final World w, final double x, final double y, final double z) {
|
private void spawnVibrant(final World w, final double x, final double y, final double z) {
|
||||||
if (AppEng.proxy.shouldAddParticles(Platform.getRandom())) {
|
if (AppEng.proxy.shouldAddParticles(Platform.getRandom())) {
|
||||||
final double d0 = (Platform.getRandomFloat() - 0.5F) * 0.26D;
|
final double d0 = (Platform.getRandomFloat() - 0.5F) * 0.26D;
|
||||||
@@ -205,15 +186,6 @@ public class ClientHelper extends ServerHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void spawnCrafting(final World w, final double posX, final double posY, final double posZ) {
|
|
||||||
final float x = (float) (((Platform.getRandomInt() % 100) * 0.01) - 0.5) * 0.7f;
|
|
||||||
final float y = (float) (((Platform.getRandomInt() % 100) * 0.01) - 0.5) * 0.7f;
|
|
||||||
final float z = (float) (((Platform.getRandomInt() % 100) * 0.01) - 0.5) * 0.7f;
|
|
||||||
|
|
||||||
Minecraft.getInstance().particles.addParticle(CraftingFx.TYPE, posX + x, posY + y, posZ + z, -x * 0.2, -y * 0.2,
|
|
||||||
-z * 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void spawnEnergy(final World w, final double posX, final double posY, final double posZ) {
|
private void spawnEnergy(final World w, final double posX, final double posY, final double posZ) {
|
||||||
final float x = (float) (((Platform.getRandomInt() % 100) * 0.01) - 0.5) * 0.7f;
|
final float x = (float) (((Platform.getRandomInt() % 100) * 0.01) - 0.5) * 0.7f;
|
||||||
final float y = (float) (((Platform.getRandomInt() % 100) * 0.01) - 0.5) * 0.7f;
|
final float y = (float) (((Platform.getRandomInt() % 100) * 0.01) - 0.5) * 0.7f;
|
||||||
|
|||||||
@@ -19,5 +19,5 @@
|
|||||||
package appeng.client;
|
package appeng.client;
|
||||||
|
|
||||||
public enum EffectType {
|
public enum EffectType {
|
||||||
Energy, Lightning, Vibrant, Crafting, Assembler, LightningArc
|
Energy, Lightning, Vibrant, LightningArc
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,230 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Applied Energistics 2.
|
|
||||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
|
||||||
*
|
|
||||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package appeng.client.render.effects;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
|
||||||
import com.mojang.brigadier.StringReader;
|
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|
||||||
|
|
||||||
import net.minecraft.client.particle.IAnimatedSprite;
|
|
||||||
import net.minecraft.client.particle.IParticleFactory;
|
|
||||||
import net.minecraft.client.particle.IParticleRenderType;
|
|
||||||
import net.minecraft.client.particle.Particle;
|
|
||||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
|
||||||
import net.minecraft.command.arguments.ItemInput;
|
|
||||||
import net.minecraft.command.arguments.ItemParser;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.network.PacketBuffer;
|
|
||||||
import net.minecraft.particles.BasicParticleType;
|
|
||||||
import net.minecraft.particles.IParticleData;
|
|
||||||
import net.minecraft.particles.ItemParticleData;
|
|
||||||
import net.minecraft.particles.ParticleType;
|
|
||||||
import net.minecraft.util.registry.Registry;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
|
||||||
|
|
||||||
import appeng.api.storage.data.IAEItemStack;
|
|
||||||
import appeng.client.EffectType;
|
|
||||||
import appeng.core.AppEng;
|
|
||||||
import appeng.entity.EntityFloatingItem;
|
|
||||||
import appeng.entity.ICanDie;
|
|
||||||
|
|
||||||
public class AssemblerFX extends Particle implements ICanDie {
|
|
||||||
|
|
||||||
public static final ParticleType<AssemblerParticleData> TYPE = new ParticleType<>(false,
|
|
||||||
new AssemblerParticleData.Deserializer());
|
|
||||||
|
|
||||||
static {
|
|
||||||
TYPE.setRegistryName(AppEng.MOD_ID, "assembler_fx");
|
|
||||||
}
|
|
||||||
|
|
||||||
private final EntityFloatingItem fi;
|
|
||||||
private final float speed;
|
|
||||||
private float time = 0;
|
|
||||||
|
|
||||||
public AssemblerFX(final World w, final double x, final double y, final double z, final double r, final double g,
|
|
||||||
final double b, final float speed, final ItemStack displayItem) {
|
|
||||||
super(w, x, y, z, r, g, b);
|
|
||||||
this.motionX = 0;
|
|
||||||
this.motionY = 0;
|
|
||||||
this.motionZ = 0;
|
|
||||||
this.speed = speed;
|
|
||||||
this.fi = new EntityFloatingItem(this, w, x, y, z, displayItem);
|
|
||||||
w.addEntity(this.fi);
|
|
||||||
this.maxAge = (int) Math.ceil(Math.max(1, 100.0f / speed)) + 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDead() {
|
|
||||||
return this.isExpired;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBrightnessForRender(final float par1) {
|
|
||||||
final int j1 = 13;
|
|
||||||
return j1 << 20 | j1 << 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick() {
|
|
||||||
this.prevPosX = this.posX;
|
|
||||||
this.prevPosY = this.posY;
|
|
||||||
this.prevPosZ = this.posZ;
|
|
||||||
|
|
||||||
if (this.age++ >= this.maxAge) {
|
|
||||||
this.setExpired();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.motionY -= 0.04D * this.particleGravity;
|
|
||||||
this.move(this.motionX, this.motionY, this.motionZ);
|
|
||||||
this.motionX *= 0.9800000190734863D;
|
|
||||||
this.motionY *= 0.9800000190734863D;
|
|
||||||
this.motionZ *= 0.9800000190734863D;
|
|
||||||
|
|
||||||
if (this.isExpired) {
|
|
||||||
this.fi.remove();
|
|
||||||
} else {
|
|
||||||
final float lifeSpan = (float) this.age / (float) this.maxAge;
|
|
||||||
this.fi.setProgress(lifeSpan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IParticleRenderType getRenderType() {
|
|
||||||
return IParticleRenderType.NO_RENDER;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderParticle(IVertexBuilder buffer, ActiveRenderInfo renderInfo, float partialTicks) {
|
|
||||||
this.time += partialTicks;
|
|
||||||
if (this.time > 4.0) {
|
|
||||||
this.time -= 4.0;
|
|
||||||
// if ( AppEng.proxy.shouldAddParticles( r ) )
|
|
||||||
for (int x = 0; x < (int) Math.ceil(this.speed / 5); x++) {
|
|
||||||
AppEng.proxy.spawnEffect(EffectType.Crafting, this.world, this.posX, this.posY, this.posZ, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class AssemblerParticleData implements IParticleData {
|
|
||||||
|
|
||||||
private final float r;
|
|
||||||
private final float g;
|
|
||||||
private final float b;
|
|
||||||
private final float speed;
|
|
||||||
private final ItemStack itemStack;
|
|
||||||
|
|
||||||
public AssemblerParticleData(float r, float g, float b, float speed, ItemStack itemStack) {
|
|
||||||
this.r = r;
|
|
||||||
this.g = g;
|
|
||||||
this.b = b;
|
|
||||||
this.speed = speed;
|
|
||||||
this.itemStack = itemStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ParticleType<?> getType() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(PacketBuffer buffer) {
|
|
||||||
buffer.writeFloat(r);
|
|
||||||
buffer.writeFloat(g);
|
|
||||||
buffer.writeFloat(b);
|
|
||||||
buffer.writeFloat(speed);
|
|
||||||
buffer.writeItemStack(itemStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Deserializer implements IDeserializer<AssemblerParticleData> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AssemblerParticleData deserialize(ParticleType<AssemblerParticleData> particleTypeIn,
|
|
||||||
StringReader reader) throws CommandSyntaxException {
|
|
||||||
reader.expect(' ');
|
|
||||||
float r = reader.readFloat();
|
|
||||||
reader.expect(' ');
|
|
||||||
float g = reader.readFloat();
|
|
||||||
reader.expect(' ');
|
|
||||||
float b = reader.readFloat();
|
|
||||||
reader.expect(' ');
|
|
||||||
float speed = reader.readFloat();
|
|
||||||
reader.expect(' ');
|
|
||||||
ItemParser itemparser = (new ItemParser(reader, false)).parse();
|
|
||||||
ItemStack itemstack = (new ItemInput(itemparser.getItem(), itemparser.getNbt())).createStack(1, false);
|
|
||||||
return new AssemblerParticleData(r, g, b, speed, itemstack);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AssemblerParticleData read(ParticleType<AssemblerParticleData> particleTypeIn, PacketBuffer buffer) {
|
|
||||||
float r = buffer.readFloat();
|
|
||||||
float g = buffer.readFloat();
|
|
||||||
float b = buffer.readFloat();
|
|
||||||
float speed = buffer.readFloat();
|
|
||||||
ItemStack itemStack = buffer.readItemStack();
|
|
||||||
return new AssemblerParticleData(r, g, b, speed, itemStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getParameters() {
|
|
||||||
return String.format(Locale.ROOT, "%s %.2f %.2f %.2f %.2f ", Registry.PARTICLE_TYPE.getKey(this.getType()),
|
|
||||||
this.r, this.g, this.b, this.speed)
|
|
||||||
+ (new ItemInput(this.itemStack.getItem(), this.itemStack.getTag())).serialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getR() {
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getG() {
|
|
||||||
return g;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getB() {
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getSpeed() {
|
|
||||||
return speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemStack getItemStack() {
|
|
||||||
return itemStack;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
|
||||||
public static class Factory implements IParticleFactory<AssemblerParticleData> {
|
|
||||||
public Factory(IAnimatedSprite spriteSet) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Particle makeParticle(AssemblerParticleData data, World world, double x, double y, double z,
|
|
||||||
double xSpeed, double ySpeed, double zSpeed) {
|
|
||||||
return new AssemblerFX(world, x, y, z, data.r, data.g, data.b, data.speed, data.itemStack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -18,31 +18,20 @@
|
|||||||
|
|
||||||
package appeng.client.render.effects;
|
package appeng.client.render.effects;
|
||||||
|
|
||||||
|
import appeng.core.AppEng;
|
||||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||||
|
|
||||||
import net.minecraft.client.particle.*;
|
import net.minecraft.client.particle.*;
|
||||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
|
||||||
import net.minecraft.client.renderer.Vector3f;
|
import net.minecraft.client.renderer.Vector3f;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.item.Item;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.item.Items;
|
|
||||||
import net.minecraft.particles.BasicParticleType;
|
import net.minecraft.particles.BasicParticleType;
|
||||||
import net.minecraft.particles.ItemParticleData;
|
|
||||||
import net.minecraft.particles.ParticleType;
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
import appeng.api.util.AEPartLocation;
|
|
||||||
import appeng.core.AppEng;
|
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
public class CraftingFx extends BreakingParticle {
|
public class CraftingFx extends SpriteTexturedParticle {
|
||||||
|
|
||||||
public static final BasicParticleType TYPE = new BasicParticleType(false);
|
public static final BasicParticleType TYPE = new BasicParticleType(false);
|
||||||
|
|
||||||
@@ -50,117 +39,99 @@ public class CraftingFx extends BreakingParticle {
|
|||||||
TYPE.setRegistryName(AppEng.MOD_ID, "crafting_fx");
|
TYPE.setRegistryName(AppEng.MOD_ID, "crafting_fx");
|
||||||
}
|
}
|
||||||
|
|
||||||
private final int startBlkX;
|
// Offset relative to center of block, is the starting point of the particle movement
|
||||||
private final int startBlkY;
|
private final float offsetX;
|
||||||
private final int startBlkZ;
|
private final float offsetY;
|
||||||
|
private final float offsetZ;
|
||||||
|
|
||||||
public CraftingFx(final World par1World, final double x, final double y, final double z,
|
public CraftingFx(final World par1World, final double x, final double y, final double z,
|
||||||
final IAnimatedSprite sprite) {
|
final IAnimatedSprite sprite) {
|
||||||
super(par1World, x, y, z, new ItemStack(Items.DIAMOND));
|
super(par1World, x, y, z);
|
||||||
|
|
||||||
|
// Pick a random normal, offset it by 0.35 and use that as the particle origin
|
||||||
|
Vector3f off = new Vector3f(
|
||||||
|
rand.nextFloat() - 0.5f,
|
||||||
|
rand.nextFloat() - 0.5f,
|
||||||
|
rand.nextFloat() - 0.5f
|
||||||
|
);
|
||||||
|
off.normalize();
|
||||||
|
off.mul(0.35f);
|
||||||
|
offsetX = off.getX();
|
||||||
|
offsetY = off.getY();
|
||||||
|
offsetZ = off.getZ();
|
||||||
|
|
||||||
this.particleGravity = 0;
|
this.particleGravity = 0;
|
||||||
this.particleBlue = 1;
|
this.particleBlue = 1;
|
||||||
this.particleGreen = 0.9f;
|
this.particleGreen = 0.9f;
|
||||||
this.particleRed = 1;
|
this.particleRed = 1;
|
||||||
this.particleAlpha = 1.3f;
|
|
||||||
this.particleScale = 1.5f;
|
|
||||||
this.selectSpriteRandomly(sprite);
|
this.selectSpriteRandomly(sprite);
|
||||||
this.maxAge /= 1.2;
|
this.maxAge /= 1.2;
|
||||||
|
this.canCollide = false; // we're INSIDE the block anyway
|
||||||
this.startBlkX = MathHelper.floor(this.posX);
|
|
||||||
this.startBlkY = MathHelper.floor(this.posY);
|
|
||||||
this.startBlkZ = MathHelper.floor(this.posZ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderParticle(IVertexBuilder buffer, ActiveRenderInfo renderInfo, float partialTicks) {
|
public void renderParticle(IVertexBuilder buffer, ActiveRenderInfo renderInfo, float partialTicks) {
|
||||||
|
|
||||||
if (partialTicks < 0 || partialTicks > 1) {
|
float f = (this.age + partialTicks) / (float) this.maxAge;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float offX = (float) (MathHelper.lerp(partialTicks, this.prevPosX, this.posX));
|
float offX = (float) posX + MathHelper.lerp(f, offsetX, 0);
|
||||||
float offY = (float) (MathHelper.lerp(partialTicks, this.prevPosY, this.posY));
|
float offY = (float) posY + MathHelper.lerp(f, offsetY, 0);
|
||||||
float offZ = (float) (MathHelper.lerp(partialTicks, this.prevPosZ, this.posZ));
|
float offZ = (float) posZ + MathHelper.lerp(f, offsetZ, 0);
|
||||||
|
float alpha = MathHelper.lerp(easeOutCirc(f), 1.3f, 0.1f);
|
||||||
|
float scale = MathHelper.lerp(easeOutCirc(f), 0.13f, 0.0f);
|
||||||
|
|
||||||
final int blkX = MathHelper.floor(offX);
|
|
||||||
final int blkY = MathHelper.floor(offY);
|
|
||||||
final int blkZ = MathHelper.floor(offZ);
|
|
||||||
// I believe this particle is same as breaking particle, but should not exit the
|
// I believe this particle is same as breaking particle, but should not exit the
|
||||||
// original block it was
|
// original block it was
|
||||||
// spawned in (which is encased in glass)
|
// spawned in (which is encased in glass)
|
||||||
if (blkX == this.startBlkX && blkY == this.startBlkY && blkZ == this.startBlkZ) {
|
Vec3d vec3d = renderInfo.getProjectedView();
|
||||||
Vec3d vec3d = renderInfo.getProjectedView();
|
offX -= vec3d.x;
|
||||||
offX -= vec3d.x;
|
offY -= vec3d.y;
|
||||||
offY -= vec3d.y;
|
offZ -= vec3d.z;
|
||||||
offZ -= vec3d.z;
|
|
||||||
|
|
||||||
Vector3f[] avector3f = new Vector3f[] { new Vector3f(-1.0F, -1.0F, 0.0F), new Vector3f(-1.0F, 1.0F, 0.0F),
|
Vector3f[] avector3f = new Vector3f[] { new Vector3f(-1.0F, -1.0F, 0.0F), new Vector3f(-1.0F, 1.0F, 0.0F),
|
||||||
new Vector3f(1.0F, 1.0F, 0.0F), new Vector3f(1.0F, -1.0F, 0.0F) };
|
new Vector3f(1.0F, 1.0F, 0.0F), new Vector3f(1.0F, -1.0F, 0.0F) };
|
||||||
float scale = this.getScale(partialTicks);
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
Vector3f vector3f = avector3f[i];
|
Vector3f vector3f = avector3f[i];
|
||||||
vector3f.transform(renderInfo.getRotation());
|
vector3f.transform(renderInfo.getRotation());
|
||||||
vector3f.mul(scale);
|
vector3f.mul(scale);
|
||||||
vector3f.add(offX, offY, offZ);
|
vector3f.add(offX, offY, offZ);
|
||||||
}
|
|
||||||
|
|
||||||
float minU = this.getMinU();
|
|
||||||
float maxU = this.getMaxU();
|
|
||||||
float minV = this.getMinV();
|
|
||||||
float maxV = this.getMaxV();
|
|
||||||
int j = this.getBrightnessForRender(partialTicks);
|
|
||||||
buffer.pos(avector3f[0].getX(), avector3f[0].getY(), avector3f[0].getZ()).tex(maxU, maxV)
|
|
||||||
.color(this.particleRed, this.particleGreen, this.particleBlue, this.particleAlpha).lightmap(j)
|
|
||||||
.endVertex();
|
|
||||||
buffer.pos(avector3f[1].getX(), avector3f[1].getY(), avector3f[1].getZ()).tex(maxU, minV)
|
|
||||||
.color(this.particleRed, this.particleGreen, this.particleBlue, this.particleAlpha).lightmap(j)
|
|
||||||
.endVertex();
|
|
||||||
buffer.pos(avector3f[2].getX(), avector3f[2].getY(), avector3f[2].getZ()).tex(minU, minV)
|
|
||||||
.color(this.particleRed, this.particleGreen, this.particleBlue, this.particleAlpha).lightmap(j)
|
|
||||||
.endVertex();
|
|
||||||
buffer.pos(avector3f[3].getX(), avector3f[3].getY(), avector3f[3].getZ()).tex(minU, maxV)
|
|
||||||
.color(this.particleRed, this.particleGreen, this.particleBlue, this.particleAlpha).lightmap(j)
|
|
||||||
.endVertex();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float minU = this.getMinU();
|
||||||
|
float maxU = this.getMaxU();
|
||||||
|
float minV = this.getMinV();
|
||||||
|
float maxV = this.getMaxV();
|
||||||
|
int j = 15728880; // full brightness
|
||||||
|
buffer.pos(avector3f[0].getX(), avector3f[0].getY(), avector3f[0].getZ()).tex(maxU, maxV)
|
||||||
|
.color(this.particleRed, this.particleGreen, this.particleBlue, alpha).lightmap(j)
|
||||||
|
.endVertex();
|
||||||
|
buffer.pos(avector3f[1].getX(), avector3f[1].getY(), avector3f[1].getZ()).tex(maxU, minV)
|
||||||
|
.color(this.particleRed, this.particleGreen, this.particleBlue, alpha).lightmap(j)
|
||||||
|
.endVertex();
|
||||||
|
buffer.pos(avector3f[2].getX(), avector3f[2].getY(), avector3f[2].getZ()).tex(minU, minV)
|
||||||
|
.color(this.particleRed, this.particleGreen, this.particleBlue, alpha).lightmap(j)
|
||||||
|
.endVertex();
|
||||||
|
buffer.pos(avector3f[3].getX(), avector3f[3].getY(), avector3f[3].getZ()).tex(minU, maxV)
|
||||||
|
.color(this.particleRed, this.particleGreen, this.particleBlue, alpha).lightmap(j)
|
||||||
|
.endVertex();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fromItem(final AEPartLocation d) {
|
// https://easings.net/#easeOutCirc
|
||||||
this.posX += 0.2 * d.xOffset;
|
private static float easeOutCirc(float x) {
|
||||||
this.posY += 0.2 * d.yOffset;
|
return (float) Math.sqrt(1 - Math.pow(x - 1, 2));
|
||||||
this.posZ += 0.2 * d.zOffset;
|
}
|
||||||
this.particleScale *= 0.8f;
|
|
||||||
|
@Override
|
||||||
|
public IParticleRenderType getRenderType() {
|
||||||
|
return IParticleRenderType.PARTICLE_SHEET_TRANSLUCENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
this.prevPosX = this.posX;
|
|
||||||
this.prevPosY = this.posY;
|
|
||||||
this.prevPosZ = this.posZ;
|
|
||||||
|
|
||||||
if (this.age++ >= this.maxAge) {
|
if (this.age++ >= this.maxAge) {
|
||||||
this.setExpired();
|
this.setExpired();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.motionY -= 0.04D * this.particleGravity;
|
|
||||||
this.move(this.motionX, this.motionY, this.motionZ);
|
|
||||||
this.motionX *= 0.9800000190734863D;
|
|
||||||
this.motionY *= 0.9800000190734863D;
|
|
||||||
this.motionZ *= 0.9800000190734863D;
|
|
||||||
this.particleScale *= 0.51f;
|
|
||||||
this.particleAlpha *= 0.51f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMotionX(float motionX) {
|
|
||||||
this.motionX = motionX;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMotionY(float motionY) {
|
|
||||||
this.motionY = motionY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMotionZ(float motionZ) {
|
|
||||||
this.motionZ = motionZ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
|||||||
@@ -182,7 +182,6 @@ public final class AppEng {
|
|||||||
((ClientHelper) proxy).clientInit();
|
((ClientHelper) proxy).clientInit();
|
||||||
|
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntityTinyTNTPrimed.TYPE, RenderTinyTNTPrimed::new);
|
RenderingRegistry.registerEntityRenderingHandler(EntityTinyTNTPrimed.TYPE, RenderTinyTNTPrimed::new);
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntityFloatingItem.TYPE, RenderFloatingItem::new);
|
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntitySingularity.TYPE,
|
RenderingRegistry.registerEntityRenderingHandler(EntitySingularity.TYPE,
|
||||||
m -> new ItemRenderer(m, Minecraft.getInstance().getItemRenderer()));
|
m -> new ItemRenderer(m, Minecraft.getInstance().getItemRenderer()));
|
||||||
RenderingRegistry.registerEntityRenderingHandler(EntityGrowingCrystal.TYPE,
|
RenderingRegistry.registerEntityRenderingHandler(EntityGrowingCrystal.TYPE,
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package appeng.core;
|
package appeng.core;
|
||||||
|
|
||||||
|
import appeng.tile.crafting.MolecularAssemblerRenderer;
|
||||||
import net.minecraft.advancements.CriteriaTriggers;
|
import net.minecraft.advancements.CriteriaTriggers;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
@@ -90,7 +91,6 @@ import appeng.core.features.registries.cell.CreativeCellHandler;
|
|||||||
import appeng.core.stats.AdvancementTriggers;
|
import appeng.core.stats.AdvancementTriggers;
|
||||||
import appeng.core.stats.AeStats;
|
import appeng.core.stats.AeStats;
|
||||||
import appeng.core.stats.PartItemPredicate;
|
import appeng.core.stats.PartItemPredicate;
|
||||||
import appeng.entity.EntityFloatingItem;
|
|
||||||
import appeng.fluids.client.gui.*;
|
import appeng.fluids.client.gui.*;
|
||||||
import appeng.fluids.container.*;
|
import appeng.fluids.container.*;
|
||||||
import appeng.fluids.registries.BasicFluidCellGuiHandler;
|
import appeng.fluids.registries.BasicFluidCellGuiHandler;
|
||||||
@@ -173,6 +173,7 @@ final class Registration {
|
|||||||
ModelLoader.addSpecialModel(BiometricCardModel.MODEL_BASE);
|
ModelLoader.addSpecialModel(BiometricCardModel.MODEL_BASE);
|
||||||
ModelLoader.addSpecialModel(MemoryCardModel.MODEL_BASE);
|
ModelLoader.addSpecialModel(MemoryCardModel.MODEL_BASE);
|
||||||
DriveModel.DEPENDENCIES.forEach(ModelLoader::addSpecialModel);
|
DriveModel.DEPENDENCIES.forEach(ModelLoader::addSpecialModel);
|
||||||
|
ModelLoader.addSpecialModel(MolecularAssemblerRenderer.LIGHTS_MODEL);
|
||||||
|
|
||||||
PartModels partModels = (PartModels) Api.INSTANCE.registries().partModels();
|
PartModels partModels = (PartModels) Api.INSTANCE.registries().partModels();
|
||||||
partModels.getModels().forEach(ModelLoader::addSpecialModel);
|
partModels.getModels().forEach(ModelLoader::addSpecialModel);
|
||||||
@@ -357,11 +358,6 @@ final class Registration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void registerEntities(RegistryEvent.Register<EntityType<?>> event) {
|
public void registerEntities(RegistryEvent.Register<EntityType<?>> event) {
|
||||||
// Special case only used on the client-side
|
|
||||||
EntityFloatingItem.TYPE = EntityType.Builder
|
|
||||||
.<EntityFloatingItem>create(EntityFloatingItem::new, EntityClassification.MISC)
|
|
||||||
.build("appliedenergistics2:floating_item");
|
|
||||||
|
|
||||||
final IForgeRegistry<EntityType<?>> registry = event.getRegistry();
|
final IForgeRegistry<EntityType<?>> registry = event.getRegistry();
|
||||||
// TODO: Do not use the internal API
|
// TODO: Do not use the internal API
|
||||||
final ApiDefinitions definitions = Api.INSTANCE.definitions();
|
final ApiDefinitions definitions = Api.INSTANCE.definitions();
|
||||||
@@ -372,12 +368,15 @@ final class Registration {
|
|||||||
public void registerParticleTypes(RegistryEvent.Register<ParticleType<?>> event) {
|
public void registerParticleTypes(RegistryEvent.Register<ParticleType<?>> event) {
|
||||||
final IForgeRegistry<ParticleType<?>> registry = event.getRegistry();
|
final IForgeRegistry<ParticleType<?>> registry = event.getRegistry();
|
||||||
registry.register(ChargedOreFX.TYPE);
|
registry.register(ChargedOreFX.TYPE);
|
||||||
registry.register(VibrantFX.TYPE);
|
registry.register(CraftingFx.TYPE);
|
||||||
|
registry.register(EnergyFx.TYPE);
|
||||||
|
registry.register(LightningArcFX.TYPE);
|
||||||
registry.register(LightningFX.TYPE);
|
registry.register(LightningFX.TYPE);
|
||||||
|
registry.register(MatterCannonFX.TYPE);
|
||||||
|
registry.register(VibrantFX.TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerParticleFactories(ParticleFactoryRegisterEvent event) {
|
public void registerParticleFactories(ParticleFactoryRegisterEvent event) {
|
||||||
Minecraft.getInstance().particles.registerFactory(AssemblerFX.TYPE, AssemblerFX.Factory::new);
|
|
||||||
Minecraft.getInstance().particles.registerFactory(ChargedOreFX.TYPE, ChargedOreFX.Factory::new);
|
Minecraft.getInstance().particles.registerFactory(ChargedOreFX.TYPE, ChargedOreFX.Factory::new);
|
||||||
Minecraft.getInstance().particles.registerFactory(CraftingFx.TYPE, CraftingFx.Factory::new);
|
Minecraft.getInstance().particles.registerFactory(CraftingFx.TYPE, CraftingFx.Factory::new);
|
||||||
Minecraft.getInstance().particles.registerFactory(EnergyFx.TYPE, EnergyFx.Factory::new);
|
Minecraft.getInstance().particles.registerFactory(EnergyFx.TYPE, EnergyFx.Factory::new);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import static appeng.block.AEBaseBlock.defaultProps;
|
|||||||
import static appeng.block.crafting.AbstractCraftingUnitBlock.CraftingUnitType;
|
import static appeng.block.crafting.AbstractCraftingUnitBlock.CraftingUnitType;
|
||||||
import static appeng.decorative.solid.BlockSkyStone.SkystoneType;
|
import static appeng.decorative.solid.BlockSkyStone.SkystoneType;
|
||||||
|
|
||||||
|
import appeng.tile.crafting.*;
|
||||||
import net.minecraft.block.*;
|
import net.minecraft.block.*;
|
||||||
import net.minecraft.block.material.Material;
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
@@ -69,10 +70,6 @@ import appeng.entity.EntityTinyTNTPrimed;
|
|||||||
import appeng.fluids.block.BlockFluidInterface;
|
import appeng.fluids.block.BlockFluidInterface;
|
||||||
import appeng.fluids.tile.TileFluidInterface;
|
import appeng.fluids.tile.TileFluidInterface;
|
||||||
import appeng.hooks.DispenserBehaviorTinyTNT;
|
import appeng.hooks.DispenserBehaviorTinyTNT;
|
||||||
import appeng.tile.crafting.TileCraftingMonitorTile;
|
|
||||||
import appeng.tile.crafting.TileCraftingStorageTile;
|
|
||||||
import appeng.tile.crafting.TileCraftingTile;
|
|
||||||
import appeng.tile.crafting.TileMolecularAssembler;
|
|
||||||
import appeng.tile.grindstone.TileCrank;
|
import appeng.tile.grindstone.TileCrank;
|
||||||
import appeng.tile.grindstone.TileGrinder;
|
import appeng.tile.grindstone.TileGrinder;
|
||||||
import appeng.tile.misc.*;
|
import appeng.tile.misc.*;
|
||||||
@@ -459,18 +456,18 @@ public final class ApiBlocks implements IBlocks {
|
|||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
@Override
|
@Override
|
||||||
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
|
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
|
||||||
// FIXME: This is an old comment, check if it still applies
|
|
||||||
/**
|
|
||||||
* NOTE: This is only used to determine how to render an item being held in
|
|
||||||
* hand. For determining block rendering, the method below is used
|
|
||||||
* (canRenderInLayer).
|
|
||||||
*/
|
|
||||||
rendering.renderType(RenderType.getCutout());
|
rendering.renderType(RenderType.getCutout());
|
||||||
rendering.renderType(rt -> rt == RenderType.getCutout() || rt == RenderType.getTranslucent());
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.tileEntity(registry
|
.tileEntity(registry
|
||||||
.tileEntity("molecular_assembler", TileMolecularAssembler.class, TileMolecularAssembler::new)
|
.tileEntity("molecular_assembler", TileMolecularAssembler.class, TileMolecularAssembler::new)
|
||||||
|
.rendering(new TileEntityRenderingCustomizer<TileMolecularAssembler>() {
|
||||||
|
@Override
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public void customize(TileEntityRendering<TileMolecularAssembler> rendering) {
|
||||||
|
rendering.tileEntityRenderer(MolecularAssemblerRenderer::new);
|
||||||
|
}
|
||||||
|
})
|
||||||
.build())
|
.build())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|||||||
@@ -18,35 +18,28 @@
|
|||||||
|
|
||||||
package appeng.core.sync.packets;
|
package appeng.core.sync.packets;
|
||||||
|
|
||||||
import java.io.IOException;
|
import appeng.api.storage.data.IAEItemStack;
|
||||||
|
import appeng.core.sync.AppEngPacket;
|
||||||
|
import appeng.core.sync.network.INetworkInfo;
|
||||||
|
import appeng.tile.crafting.AssemblerAnimationStatus;
|
||||||
|
import appeng.tile.crafting.TileMolecularAssembler;
|
||||||
|
import appeng.util.item.AEItemStack;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
import appeng.api.storage.data.IAEItemStack;
|
|
||||||
import appeng.client.EffectType;
|
|
||||||
import appeng.core.AppEng;
|
|
||||||
import appeng.core.sync.AppEngPacket;
|
|
||||||
import appeng.core.sync.network.INetworkInfo;
|
|
||||||
import appeng.util.item.AEItemStack;
|
|
||||||
|
|
||||||
public class PacketAssemblerAnimation extends AppEngPacket {
|
public class PacketAssemblerAnimation extends AppEngPacket {
|
||||||
|
|
||||||
private final int x;
|
private final BlockPos pos;
|
||||||
private final int y;
|
|
||||||
private final int z;
|
|
||||||
public final byte rate;
|
public final byte rate;
|
||||||
public final IAEItemStack is;
|
public final IAEItemStack is;
|
||||||
|
|
||||||
public PacketAssemblerAnimation(final PacketBuffer stream) {
|
public PacketAssemblerAnimation(final PacketBuffer stream) {
|
||||||
this.x = stream.readInt();
|
this.pos = stream.readBlockPos();
|
||||||
this.y = stream.readInt();
|
|
||||||
this.z = stream.readInt();
|
|
||||||
this.rate = stream.readByte();
|
this.rate = stream.readByte();
|
||||||
this.is = AEItemStack.fromPacket(stream);
|
this.is = AEItemStack.fromPacket(stream);
|
||||||
}
|
}
|
||||||
@@ -57,9 +50,7 @@ public class PacketAssemblerAnimation extends AppEngPacket {
|
|||||||
final PacketBuffer data = new PacketBuffer(Unpooled.buffer());
|
final PacketBuffer data = new PacketBuffer(Unpooled.buffer());
|
||||||
|
|
||||||
data.writeInt(this.getPacketID());
|
data.writeInt(this.getPacketID());
|
||||||
data.writeInt(this.x = pos.getX());
|
data.writeBlockPos(this.pos = pos);
|
||||||
data.writeInt(this.y = pos.getY());
|
|
||||||
data.writeInt(this.z = pos.getZ());
|
|
||||||
data.writeByte(this.rate = rate);
|
data.writeByte(this.rate = rate);
|
||||||
is.writeToPacket(data);
|
is.writeToPacket(data);
|
||||||
this.is = is;
|
this.is = is;
|
||||||
@@ -70,11 +61,10 @@ public class PacketAssemblerAnimation extends AppEngPacket {
|
|||||||
@Override
|
@Override
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
public void clientPacketData(final INetworkInfo network, final PlayerEntity player) {
|
public void clientPacketData(final INetworkInfo network, final PlayerEntity player) {
|
||||||
final double d0 = 0.5d;// + ((double) (Platform.getRandomFloat() - 0.5F) * 0.26D);
|
TileEntity te = player.getEntityWorld().getTileEntity(pos);
|
||||||
final double d1 = 0.5d;// + ((double) (Platform.getRandomFloat() - 0.5F) * 0.26D);
|
if (te instanceof TileMolecularAssembler) {
|
||||||
final double d2 = 0.5d;// + ((double) (Platform.getRandomFloat() - 0.5F) * 0.26D);
|
TileMolecularAssembler ma = (TileMolecularAssembler) te;
|
||||||
|
ma.setAnimationStatus(new AssemblerAnimationStatus(rate, is.asItemStackRepresentation()));
|
||||||
AppEng.proxy.spawnEffect(EffectType.Assembler, player.getEntityWorld(), this.x + d0, this.y + d1, this.z + d2,
|
}
|
||||||
this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Applied Energistics 2.
|
|
||||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
|
||||||
*
|
|
||||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package appeng.entity;
|
|
||||||
|
|
||||||
import net.minecraft.entity.EntityType;
|
|
||||||
import net.minecraft.entity.item.ItemEntity;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
|
|
||||||
// This is not supposed to ever spawn on the server-side
|
|
||||||
public final class EntityFloatingItem extends AEBaseEntityItem {
|
|
||||||
|
|
||||||
public static EntityType<EntityFloatingItem> TYPE;
|
|
||||||
|
|
||||||
private ICanDie parent;
|
|
||||||
private int superDeath = 0;
|
|
||||||
private float progress = 0;
|
|
||||||
|
|
||||||
public EntityFloatingItem(EntityType<? extends AEBaseEntityItem> entityType, World world) {
|
|
||||||
super(entityType, world);
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityFloatingItem(final ICanDie parent, final World world, final double x, final double y, final double z,
|
|
||||||
final ItemStack stack) {
|
|
||||||
super(TYPE, world, x, y, z, stack);
|
|
||||||
this.setMotion(0, 0, 0);
|
|
||||||
this.rotationYaw = 0;
|
|
||||||
this.parent = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tick() {
|
|
||||||
if (!this.removed && this.parent.isDead()) {
|
|
||||||
this.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.superDeath > 100) {
|
|
||||||
this.remove();
|
|
||||||
}
|
|
||||||
this.superDeath++;
|
|
||||||
|
|
||||||
this.setNoDespawn();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProgress(final float progress) {
|
|
||||||
this.progress = progress;
|
|
||||||
if (this.progress > 0.99) {
|
|
||||||
this.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float getProgress() {
|
|
||||||
return this.progress;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Applied Energistics 2.
|
|
||||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
|
||||||
*
|
|
||||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package appeng.entity;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
|
||||||
import net.minecraft.client.renderer.entity.EntityRendererManager;
|
|
||||||
import net.minecraft.client.renderer.entity.ItemRenderer;
|
|
||||||
import net.minecraft.entity.item.ItemEntity;
|
|
||||||
import net.minecraft.item.BlockItem;
|
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
|
||||||
public class RenderFloatingItem extends ItemRenderer {
|
|
||||||
|
|
||||||
public RenderFloatingItem(final EntityRendererManager manager) {
|
|
||||||
super(manager, Minecraft.getInstance().getItemRenderer());
|
|
||||||
this.shadowOpaque = 0.0F;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(ItemEntity entityIn, float entityYaw, float partialTicks, MatrixStack mStack,
|
|
||||||
IRenderTypeBuffer buffers, int packedLightIn) {
|
|
||||||
if (entityIn instanceof EntityFloatingItem) {
|
|
||||||
final EntityFloatingItem efi = (EntityFloatingItem) entityIn;
|
|
||||||
if (efi.getProgress() > 0.0) {
|
|
||||||
mStack.push();
|
|
||||||
|
|
||||||
if (!(efi.getItem().getItem() instanceof BlockItem)) {
|
|
||||||
mStack.translate(0, -0.3f, 0);
|
|
||||||
} else {
|
|
||||||
mStack.translate(0, -0.2f, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
super.render(entityIn, entityYaw, 0, mStack, buffers, packedLightIn);
|
|
||||||
mStack.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean shouldBob() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package appeng.tile.crafting;
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores client-side only state about the ongoing animation for a molecular assembler.
|
||||||
|
*/
|
||||||
|
public class AssemblerAnimationStatus {
|
||||||
|
|
||||||
|
private final ItemStack is;
|
||||||
|
|
||||||
|
private final byte speed;
|
||||||
|
|
||||||
|
private final int ticksRequired;
|
||||||
|
|
||||||
|
private float accumulatedTicks;
|
||||||
|
|
||||||
|
private float ticksUntilParticles;
|
||||||
|
|
||||||
|
public AssemblerAnimationStatus(byte speed, ItemStack is) {
|
||||||
|
this.speed = speed;
|
||||||
|
this.is = is;
|
||||||
|
this.ticksRequired = (int) Math.ceil(Math.max(1, 100.0f / speed)) + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack getIs() {
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getSpeed() {
|
||||||
|
return speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getAccumulatedTicks() {
|
||||||
|
return accumulatedTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccumulatedTicks(float accumulatedTicks) {
|
||||||
|
this.accumulatedTicks = accumulatedTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getTicksUntilParticles() {
|
||||||
|
return ticksUntilParticles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTicksUntilParticles(float ticksUntilParticles) {
|
||||||
|
this.ticksUntilParticles = ticksUntilParticles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isExpired() {
|
||||||
|
return accumulatedTicks > ticksRequired;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Applied Energistics 2.
|
||||||
|
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||||
|
*
|
||||||
|
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package appeng.tile.crafting;
|
||||||
|
|
||||||
|
import appeng.client.render.effects.CraftingFx;
|
||||||
|
import appeng.core.AppEng;
|
||||||
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
|
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
|
import net.minecraft.client.renderer.ItemRenderer;
|
||||||
|
import net.minecraft.client.renderer.RenderState;
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.client.renderer.model.IBakedModel;
|
||||||
|
import net.minecraft.client.renderer.model.ItemCameraTransforms;
|
||||||
|
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||||
|
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||||
|
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||||
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
|
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||||
|
import net.minecraft.item.BlockItem;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||||
|
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the item currently being crafted by the molecular assembler, as well as
|
||||||
|
* the light strip when it's powered.
|
||||||
|
*/
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public class MolecularAssemblerRenderer extends TileEntityRenderer<TileMolecularAssembler> {
|
||||||
|
|
||||||
|
public static final ResourceLocation LIGHTS_MODEL = new ResourceLocation(AppEng.MOD_ID, "block/molecular_assembler_lights");
|
||||||
|
|
||||||
|
private static final RenderType MC_161917_RENDERTYPE_FIX = createRenderType();
|
||||||
|
|
||||||
|
private final Random particleRandom = new Random();
|
||||||
|
|
||||||
|
public MolecularAssemblerRenderer(TileEntityRendererDispatcher rendererDispatcherIn) {
|
||||||
|
super(rendererDispatcherIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(TileMolecularAssembler molecularAssembler, float partialTicks, MatrixStack ms, IRenderTypeBuffer bufferIn, int combinedLightIn, int combinedOverlayIn) {
|
||||||
|
|
||||||
|
AssemblerAnimationStatus status = molecularAssembler.getAnimationStatus();
|
||||||
|
if (status != null) {
|
||||||
|
if (!Minecraft.getInstance().isGamePaused()) {
|
||||||
|
if (status.isExpired()) {
|
||||||
|
molecularAssembler.setAnimationStatus(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
status.setAccumulatedTicks(status.getAccumulatedTicks() + partialTicks);
|
||||||
|
status.setTicksUntilParticles(status.getTicksUntilParticles() - partialTicks);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStatus(molecularAssembler, ms, bufferIn, combinedLightIn, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (molecularAssembler.isPowered()) {
|
||||||
|
renderPowerLight(ms, bufferIn, combinedLightIn, combinedOverlayIn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderPowerLight(MatrixStack ms, IRenderTypeBuffer bufferIn, int combinedLightIn, int combinedOverlayIn) {
|
||||||
|
// Render the translucent light overlay here instead of in the block, because thanks to the following MC
|
||||||
|
// bug, our particles would otherwise not be visible (because the glass pane would also render as translucent,
|
||||||
|
// even the fully transparent part)
|
||||||
|
// https://bugs.mojang.com/browse/MC-161917
|
||||||
|
Minecraft minecraft = Minecraft.getInstance();
|
||||||
|
IBakedModel lightsModel = minecraft.getModelManager().getModel(LIGHTS_MODEL);
|
||||||
|
IVertexBuilder buffer = bufferIn.getBuffer(MC_161917_RENDERTYPE_FIX);
|
||||||
|
|
||||||
|
minecraft.getBlockRendererDispatcher().getBlockModelRenderer().renderModel(
|
||||||
|
ms.getLast(), buffer, null, lightsModel, 1, 1, 1, combinedLightIn, combinedOverlayIn, EmptyModelData.INSTANCE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderStatus(TileMolecularAssembler molecularAssembler, MatrixStack ms, IRenderTypeBuffer bufferIn, int combinedLightIn, AssemblerAnimationStatus status) {
|
||||||
|
double centerX = molecularAssembler.getPos().getX() + 0.5f;
|
||||||
|
double centerY = molecularAssembler.getPos().getY() + 0.5f;
|
||||||
|
double centerZ = molecularAssembler.getPos().getZ() + 0.5f;
|
||||||
|
|
||||||
|
// Spawn crafting FX that fly towards the block's center
|
||||||
|
Minecraft minecraft = Minecraft.getInstance();
|
||||||
|
if (status.getTicksUntilParticles() <= 0) {
|
||||||
|
status.setTicksUntilParticles(4);
|
||||||
|
|
||||||
|
if (AppEng.proxy.shouldAddParticles(particleRandom)) {
|
||||||
|
for (int x = 0; x < (int) Math.ceil(status.getSpeed() / 5.0); x++) {
|
||||||
|
minecraft.particles.addParticle(
|
||||||
|
CraftingFx.TYPE,
|
||||||
|
centerX, centerY, centerZ,
|
||||||
|
0, 0, 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack is = status.getIs();
|
||||||
|
|
||||||
|
ItemRenderer itemRenderer = minecraft.getItemRenderer();
|
||||||
|
ms.push();
|
||||||
|
ms.translate(0.5, 0.5, 0.5); // Translate to center of block
|
||||||
|
|
||||||
|
if (!(is.getItem().getItem() instanceof BlockItem)) {
|
||||||
|
ms.translate(0, -0.3f, 0);
|
||||||
|
} else {
|
||||||
|
ms.translate(0, -0.2f, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
itemRenderer.renderItem(is, ItemCameraTransforms.TransformType.GROUND, combinedLightIn, OverlayTexture.NO_OVERLAY,
|
||||||
|
ms, bufferIn);
|
||||||
|
ms.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See above for when this can be removed.
|
||||||
|
* It creates a RenderType that is equivalent to {@link RenderType#getTranslucent()}, but enables
|
||||||
|
* alpha testing. This prevents the fully transparents parts of the rendered block model from
|
||||||
|
* occluding our particles.
|
||||||
|
*/
|
||||||
|
private static RenderType createRenderType() {
|
||||||
|
RenderState.TransparencyState TRANSLUCENT_TRANSPARENCY = ObfuscationReflectionHelper.getPrivateValue(RenderState.class, null, "field_228515_g_");
|
||||||
|
RenderState.TextureState mipmapBlockAtlasTexture = new RenderState.TextureState(AtlasTexture.LOCATION_BLOCKS_TEXTURE, false, true);
|
||||||
|
RenderState.LightmapState disableLightmap = new RenderState.LightmapState(false);
|
||||||
|
RenderType.State glState = RenderType.State.getBuilder().texture(mipmapBlockAtlasTexture).transparency(TRANSLUCENT_TRANSPARENCY).alpha(new RenderState.AlphaState(0.05F)).lightmap(disableLightmap).build(true);
|
||||||
|
|
||||||
|
return RenderType.makeType("ae2_translucent_alphatest", DefaultVertexFormats.POSITION_COLOR_TEX_LIGHTMAP, GL11.GL_QUADS, 256, glState);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -31,6 +31,8 @@ import net.minecraft.util.Direction;
|
|||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.server.ServerWorld;
|
import net.minecraft.world.server.ServerWorld;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.fml.hooks.BasicEventHooks;
|
import net.minecraftforge.fml.hooks.BasicEventHooks;
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
@@ -77,6 +79,8 @@ import appeng.util.inv.WrapperFilteredItemHandler;
|
|||||||
import appeng.util.inv.filter.IAEItemFilter;
|
import appeng.util.inv.filter.IAEItemFilter;
|
||||||
import appeng.util.item.AEItemStack;
|
import appeng.util.item.AEItemStack;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class TileMolecularAssembler extends AENetworkInvTile
|
public class TileMolecularAssembler extends AENetworkInvTile
|
||||||
implements IUpgradeableHost, IConfigManagerHost, IGridTickable, ICraftingMachine, IPowerChannelState {
|
implements IUpgradeableHost, IConfigManagerHost, IGridTickable, ICraftingMachine, IPowerChannelState {
|
||||||
|
|
||||||
@@ -98,6 +102,9 @@ public class TileMolecularAssembler extends AENetworkInvTile
|
|||||||
private boolean forcePlan = false;
|
private boolean forcePlan = false;
|
||||||
private boolean reboot = true;
|
private boolean reboot = true;
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
private AssemblerAnimationStatus animationStatus;
|
||||||
|
|
||||||
public TileMolecularAssembler(TileEntityType<?> tileEntityTypeIn) {
|
public TileMolecularAssembler(TileEntityType<?> tileEntityTypeIn) {
|
||||||
super(tileEntityTypeIn);
|
super(tileEntityTypeIn);
|
||||||
final ITileDefinition assembler = AEApi.instance().definitions().blocks().molecularAssembler();
|
final ITileDefinition assembler = AEApi.instance().definitions().blocks().molecularAssembler();
|
||||||
@@ -417,11 +424,13 @@ public class TileMolecularAssembler extends AENetworkInvTile
|
|||||||
|
|
||||||
this.ejectHeldItems();
|
this.ejectHeldItems();
|
||||||
|
|
||||||
final TargetPoint where = new TargetPoint(this.pos.getX(), this.pos.getY(), this.pos.getZ(), 32,
|
|
||||||
this.world.getDimension().getType());
|
|
||||||
final IAEItemStack item = AEItemStack.fromItemStack(output);
|
final IAEItemStack item = AEItemStack.fromItemStack(output);
|
||||||
NetworkHandler.instance().sendToAllAround(new PacketAssemblerAnimation(this.pos, (byte) speed, item),
|
if (item != null) {
|
||||||
where);
|
final TargetPoint where = new TargetPoint(this.pos.getX(), this.pos.getY(), this.pos.getZ(), 32,
|
||||||
|
this.world.getDimension().getType());
|
||||||
|
NetworkHandler.instance().sendToAllAround(new PacketAssemblerAnimation(this.pos, (byte) speed, item),
|
||||||
|
where);
|
||||||
|
}
|
||||||
|
|
||||||
this.saveChanges();
|
this.saveChanges();
|
||||||
this.updateSleepiness();
|
this.updateSleepiness();
|
||||||
@@ -533,6 +542,17 @@ public class TileMolecularAssembler extends AENetworkInvTile
|
|||||||
return this.isPowered;
|
return this.isPowered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public void setAnimationStatus(@Nullable AssemblerAnimationStatus status) {
|
||||||
|
this.animationStatus = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
@Nullable
|
||||||
|
public AssemblerAnimationStatus getAnimationStatus() {
|
||||||
|
return this.animationStatus;
|
||||||
|
}
|
||||||
|
|
||||||
private class CraftingGridFilter implements IAEItemFilter {
|
private class CraftingGridFilter implements IAEItemFilter {
|
||||||
private boolean hasPattern() {
|
private boolean hasPattern() {
|
||||||
return TileMolecularAssembler.this.myPlan != null
|
return TileMolecularAssembler.this.myPlan != null
|
||||||
|
|||||||
@@ -1,17 +1,7 @@
|
|||||||
{
|
{
|
||||||
"multipart": [
|
"variants": {
|
||||||
{
|
"": {
|
||||||
"apply": {
|
"model": "appliedenergistics2:block/molecular_assembler"
|
||||||
"model": "appliedenergistics2:block/molecular_assembler"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"when": {
|
|
||||||
"powered": "true"
|
|
||||||
},
|
|
||||||
"apply": {
|
|
||||||
"model": "appliedenergistics2:block/molecular_assembler_lights"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
{}
|
{
|
||||||
|
"textures": []
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"textures": ["appliedenergistics2:particles/energy"]
|
"textures": ["appliedenergistics2:energy"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"textures": []
|
||||||
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"textures": ["appliedenergistics2:particles/matter_cannon"]
|
"textures": ["appliedenergistics2:matter_cannon"]
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 242 B After Width: | Height: | Size: 242 B |
|
Before Width: | Height: | Size: 297 B After Width: | Height: | Size: 297 B |
Reference in New Issue
Block a user