From 98d6740bb27f99dc18118d02b1006989e0faf2ae Mon Sep 17 00:00:00 2001 From: Sebastian Hartte Date: Thu, 18 Jun 2020 17:14:53 +0200 Subject: [PATCH] Redo rendering of the molecular assembler and it's animation --- .../java/appeng/bootstrap/EntityBuilder.java | 8 - src/main/java/appeng/client/ClientHelper.java | 28 --- src/main/java/appeng/client/EffectType.java | 2 +- .../client/render/effects/AssemblerFX.java | 230 ------------------ .../client/render/effects/CraftingFx.java | 157 +++++------- src/main/java/appeng/core/AppEng.java | 1 - src/main/java/appeng/core/Registration.java | 15 +- .../core/api/definitions/ApiBlocks.java | 19 +- .../packets/PacketAssemblerAnimation.java | 40 ++- .../appeng/entity/EntityFloatingItem.java | 71 ------ .../appeng/entity/RenderFloatingItem.java | 64 ----- .../crafting/AssemblerAnimationStatus.java | 53 ++++ .../crafting/MolecularAssemblerRenderer.java | 154 ++++++++++++ .../tile/crafting/TileMolecularAssembler.java | 28 ++- .../blockstates/molecular_assembler.json | 18 +- .../particles/assembler_fx.json | 4 +- .../particles/crafting_fx.json | 2 +- .../particles/energy_fx.json | 3 + .../particles/matter_cannon_fx.json | 2 +- .../{particles => particle}/energy.png | Bin .../{particles => particle}/matter_cannon.png | Bin 21 files changed, 338 insertions(+), 561 deletions(-) delete mode 100644 src/main/java/appeng/client/render/effects/AssemblerFX.java delete mode 100644 src/main/java/appeng/entity/EntityFloatingItem.java delete mode 100644 src/main/java/appeng/entity/RenderFloatingItem.java create mode 100644 src/main/java/appeng/tile/crafting/AssemblerAnimationStatus.java create mode 100644 src/main/java/appeng/tile/crafting/MolecularAssemblerRenderer.java create mode 100644 src/main/resources/assets/appliedenergistics2/particles/energy_fx.json rename src/main/resources/assets/appliedenergistics2/textures/{particles => particle}/energy.png (100%) rename src/main/resources/assets/appliedenergistics2/textures/{particles => particle}/matter_cannon.png (100%) diff --git a/src/main/java/appeng/bootstrap/EntityBuilder.java b/src/main/java/appeng/bootstrap/EntityBuilder.java index 1ad4fa0b9..1b09c14b9 100644 --- a/src/main/java/appeng/bootstrap/EntityBuilder.java +++ b/src/main/java/appeng/bootstrap/EntityBuilder.java @@ -7,18 +7,10 @@ import java.util.function.Consumer; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityClassification; 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.bootstrap.components.IClientSetupComponent; import appeng.bootstrap.components.IEntityRegistrationComponent; 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. diff --git a/src/main/java/appeng/client/ClientHelper.java b/src/main/java/appeng/client/ClientHelper.java index c1a913493..ccd8fb39f 100644 --- a/src/main/java/appeng/client/ClientHelper.java +++ b/src/main/java/appeng/client/ClientHelper.java @@ -42,7 +42,6 @@ import appeng.client.render.effects.*; import appeng.core.AEConfig; import appeng.core.AppEng; import appeng.core.sync.network.NetworkHandler; -import appeng.core.sync.packets.PacketAssemblerAnimation; import appeng.core.sync.packets.PacketValueConfig; import appeng.helpers.IMouseWheelItem; import appeng.server.ServerHelper; @@ -94,15 +93,9 @@ public class ClientHelper extends ServerHelper { final double posZ, final Object o) { if (AEConfig.instance().isEnableEffects()) { switch (effect) { - case Assembler: - this.spawnAssembler(world, posX, posY, posZ, o); - return; case Vibrant: this.spawnVibrant(world, posX, posY, posZ); return; - case Crafting: - this.spawnCrafting(world, posX, posY, posZ); - return; case Energy: this.spawnEnergy(world, posX, posY, posZ); return; @@ -183,18 +176,6 @@ public class ClientHelper extends ServerHelper { // 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) { if (AppEng.proxy.shouldAddParticles(Platform.getRandom())) { 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) { 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; diff --git a/src/main/java/appeng/client/EffectType.java b/src/main/java/appeng/client/EffectType.java index 474a67a10..0a47d4812 100644 --- a/src/main/java/appeng/client/EffectType.java +++ b/src/main/java/appeng/client/EffectType.java @@ -19,5 +19,5 @@ package appeng.client; public enum EffectType { - Energy, Lightning, Vibrant, Crafting, Assembler, LightningArc + Energy, Lightning, Vibrant, LightningArc } diff --git a/src/main/java/appeng/client/render/effects/AssemblerFX.java b/src/main/java/appeng/client/render/effects/AssemblerFX.java deleted file mode 100644 index 58278a864..000000000 --- a/src/main/java/appeng/client/render/effects/AssemblerFX.java +++ /dev/null @@ -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 . - */ - -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 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 { - - @Override - public AssemblerParticleData deserialize(ParticleType 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 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 { - 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); - } - } - -} diff --git a/src/main/java/appeng/client/render/effects/CraftingFx.java b/src/main/java/appeng/client/render/effects/CraftingFx.java index c7e39f8a0..e81ff09fd 100644 --- a/src/main/java/appeng/client/render/effects/CraftingFx.java +++ b/src/main/java/appeng/client/render/effects/CraftingFx.java @@ -18,31 +18,20 @@ package appeng.client.render.effects; +import appeng.core.AppEng; import com.mojang.blaze3d.vertex.IVertexBuilder; - import net.minecraft.client.particle.*; import net.minecraft.client.renderer.ActiveRenderInfo; -import net.minecraft.client.renderer.BufferBuilder; 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.ItemParticleData; -import net.minecraft.particles.ParticleType; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -import appeng.api.util.AEPartLocation; -import appeng.core.AppEng; - @OnlyIn(Dist.CLIENT) -public class CraftingFx extends BreakingParticle { +public class CraftingFx extends SpriteTexturedParticle { public static final BasicParticleType TYPE = new BasicParticleType(false); @@ -50,117 +39,99 @@ public class CraftingFx extends BreakingParticle { TYPE.setRegistryName(AppEng.MOD_ID, "crafting_fx"); } - private final int startBlkX; - private final int startBlkY; - private final int startBlkZ; + // Offset relative to center of block, is the starting point of the particle movement + private final float offsetX; + private final float offsetY; + private final float offsetZ; public CraftingFx(final World par1World, final double x, final double y, final double z, 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.particleBlue = 1; this.particleGreen = 0.9f; this.particleRed = 1; - this.particleAlpha = 1.3f; - this.particleScale = 1.5f; this.selectSpriteRandomly(sprite); this.maxAge /= 1.2; - - this.startBlkX = MathHelper.floor(this.posX); - this.startBlkY = MathHelper.floor(this.posY); - this.startBlkZ = MathHelper.floor(this.posZ); + this.canCollide = false; // we're INSIDE the block anyway } @Override public void renderParticle(IVertexBuilder buffer, ActiveRenderInfo renderInfo, float partialTicks) { - if (partialTicks < 0 || partialTicks > 1) { - return; - } + float f = (this.age + partialTicks) / (float) this.maxAge; - float offX = (float) (MathHelper.lerp(partialTicks, this.prevPosX, this.posX)); - float offY = (float) (MathHelper.lerp(partialTicks, this.prevPosY, this.posY)); - float offZ = (float) (MathHelper.lerp(partialTicks, this.prevPosZ, this.posZ)); + float offX = (float) posX + MathHelper.lerp(f, offsetX, 0); + float offY = (float) posY + MathHelper.lerp(f, offsetY, 0); + 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 // original block it was // spawned in (which is encased in glass) - if (blkX == this.startBlkX && blkY == this.startBlkY && blkZ == this.startBlkZ) { - Vec3d vec3d = renderInfo.getProjectedView(); - offX -= vec3d.x; - offY -= vec3d.y; - offZ -= vec3d.z; + Vec3d vec3d = renderInfo.getProjectedView(); + offX -= vec3d.x; + offY -= vec3d.y; + offZ -= vec3d.z; - 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) }; - float scale = this.getScale(partialTicks); + 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) }; - for (int i = 0; i < 4; ++i) { - Vector3f vector3f = avector3f[i]; - vector3f.transform(renderInfo.getRotation()); - vector3f.mul(scale); - 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(); + for (int i = 0; i < 4; ++i) { + Vector3f vector3f = avector3f[i]; + vector3f.transform(renderInfo.getRotation()); + vector3f.mul(scale); + vector3f.add(offX, offY, offZ); } + + 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) { - this.posX += 0.2 * d.xOffset; - this.posY += 0.2 * d.yOffset; - this.posZ += 0.2 * d.zOffset; - this.particleScale *= 0.8f; + // https://easings.net/#easeOutCirc + private static float easeOutCirc(float x) { + return (float) Math.sqrt(1 - Math.pow(x - 1, 2)); + } + + @Override + public IParticleRenderType getRenderType() { + return IParticleRenderType.PARTICLE_SHEET_TRANSLUCENT; } @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; - 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) diff --git a/src/main/java/appeng/core/AppEng.java b/src/main/java/appeng/core/AppEng.java index 5e45ceebb..9674ce445 100644 --- a/src/main/java/appeng/core/AppEng.java +++ b/src/main/java/appeng/core/AppEng.java @@ -182,7 +182,6 @@ public final class AppEng { ((ClientHelper) proxy).clientInit(); RenderingRegistry.registerEntityRenderingHandler(EntityTinyTNTPrimed.TYPE, RenderTinyTNTPrimed::new); - RenderingRegistry.registerEntityRenderingHandler(EntityFloatingItem.TYPE, RenderFloatingItem::new); RenderingRegistry.registerEntityRenderingHandler(EntitySingularity.TYPE, m -> new ItemRenderer(m, Minecraft.getInstance().getItemRenderer())); RenderingRegistry.registerEntityRenderingHandler(EntityGrowingCrystal.TYPE, diff --git a/src/main/java/appeng/core/Registration.java b/src/main/java/appeng/core/Registration.java index 3d558067f..6db0623d1 100644 --- a/src/main/java/appeng/core/Registration.java +++ b/src/main/java/appeng/core/Registration.java @@ -18,6 +18,7 @@ package appeng.core; +import appeng.tile.crafting.MolecularAssemblerRenderer; import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.block.Block; 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.AeStats; import appeng.core.stats.PartItemPredicate; -import appeng.entity.EntityFloatingItem; import appeng.fluids.client.gui.*; import appeng.fluids.container.*; import appeng.fluids.registries.BasicFluidCellGuiHandler; @@ -173,6 +173,7 @@ final class Registration { ModelLoader.addSpecialModel(BiometricCardModel.MODEL_BASE); ModelLoader.addSpecialModel(MemoryCardModel.MODEL_BASE); DriveModel.DEPENDENCIES.forEach(ModelLoader::addSpecialModel); + ModelLoader.addSpecialModel(MolecularAssemblerRenderer.LIGHTS_MODEL); PartModels partModels = (PartModels) Api.INSTANCE.registries().partModels(); partModels.getModels().forEach(ModelLoader::addSpecialModel); @@ -357,11 +358,6 @@ final class Registration { } public void registerEntities(RegistryEvent.Register> event) { - // Special case only used on the client-side - EntityFloatingItem.TYPE = EntityType.Builder - .create(EntityFloatingItem::new, EntityClassification.MISC) - .build("appliedenergistics2:floating_item"); - final IForgeRegistry> registry = event.getRegistry(); // TODO: Do not use the internal API final ApiDefinitions definitions = Api.INSTANCE.definitions(); @@ -372,12 +368,15 @@ final class Registration { public void registerParticleTypes(RegistryEvent.Register> event) { final IForgeRegistry> registry = event.getRegistry(); 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(MatterCannonFX.TYPE); + registry.register(VibrantFX.TYPE); } 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(CraftingFx.TYPE, CraftingFx.Factory::new); Minecraft.getInstance().particles.registerFactory(EnergyFx.TYPE, EnergyFx.Factory::new); diff --git a/src/main/java/appeng/core/api/definitions/ApiBlocks.java b/src/main/java/appeng/core/api/definitions/ApiBlocks.java index d61b9710a..172f6a5e4 100644 --- a/src/main/java/appeng/core/api/definitions/ApiBlocks.java +++ b/src/main/java/appeng/core/api/definitions/ApiBlocks.java @@ -22,6 +22,7 @@ import static appeng.block.AEBaseBlock.defaultProps; import static appeng.block.crafting.AbstractCraftingUnitBlock.CraftingUnitType; import static appeng.decorative.solid.BlockSkyStone.SkystoneType; +import appeng.tile.crafting.*; import net.minecraft.block.*; import net.minecraft.block.material.Material; import net.minecraft.client.renderer.RenderType; @@ -69,10 +70,6 @@ import appeng.entity.EntityTinyTNTPrimed; import appeng.fluids.block.BlockFluidInterface; import appeng.fluids.tile.TileFluidInterface; 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.TileGrinder; import appeng.tile.misc.*; @@ -459,18 +456,18 @@ public final class ApiBlocks implements IBlocks { @OnlyIn(Dist.CLIENT) @Override 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(rt -> rt == RenderType.getCutout() || rt == RenderType.getTranslucent()); } }) .tileEntity(registry .tileEntity("molecular_assembler", TileMolecularAssembler.class, TileMolecularAssembler::new) + .rendering(new TileEntityRenderingCustomizer() { + @Override + @OnlyIn(Dist.CLIENT) + public void customize(TileEntityRendering rendering) { + rendering.tileEntityRenderer(MolecularAssemblerRenderer::new); + } + }) .build()) .build(); diff --git a/src/main/java/appeng/core/sync/packets/PacketAssemblerAnimation.java b/src/main/java/appeng/core/sync/packets/PacketAssemblerAnimation.java index ca827ece7..9279c50c9 100644 --- a/src/main/java/appeng/core/sync/packets/PacketAssemblerAnimation.java +++ b/src/main/java/appeng/core/sync/packets/PacketAssemblerAnimation.java @@ -18,35 +18,28 @@ 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 net.minecraft.entity.player.PlayerEntity; import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; 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.core.sync.AppEngPacket; -import appeng.core.sync.network.INetworkInfo; -import appeng.util.item.AEItemStack; - public class PacketAssemblerAnimation extends AppEngPacket { - private final int x; - private final int y; - private final int z; + private final BlockPos pos; public final byte rate; public final IAEItemStack is; public PacketAssemblerAnimation(final PacketBuffer stream) { - this.x = stream.readInt(); - this.y = stream.readInt(); - this.z = stream.readInt(); + this.pos = stream.readBlockPos(); this.rate = stream.readByte(); this.is = AEItemStack.fromPacket(stream); } @@ -57,9 +50,7 @@ public class PacketAssemblerAnimation extends AppEngPacket { final PacketBuffer data = new PacketBuffer(Unpooled.buffer()); data.writeInt(this.getPacketID()); - data.writeInt(this.x = pos.getX()); - data.writeInt(this.y = pos.getY()); - data.writeInt(this.z = pos.getZ()); + data.writeBlockPos(this.pos = pos); data.writeByte(this.rate = rate); is.writeToPacket(data); this.is = is; @@ -70,11 +61,10 @@ public class PacketAssemblerAnimation extends AppEngPacket { @Override @OnlyIn(Dist.CLIENT) public void clientPacketData(final INetworkInfo network, final PlayerEntity player) { - final double d0 = 0.5d;// + ((double) (Platform.getRandomFloat() - 0.5F) * 0.26D); - final double d1 = 0.5d;// + ((double) (Platform.getRandomFloat() - 0.5F) * 0.26D); - final double d2 = 0.5d;// + ((double) (Platform.getRandomFloat() - 0.5F) * 0.26D); - - AppEng.proxy.spawnEffect(EffectType.Assembler, player.getEntityWorld(), this.x + d0, this.y + d1, this.z + d2, - this); + TileEntity te = player.getEntityWorld().getTileEntity(pos); + if (te instanceof TileMolecularAssembler) { + TileMolecularAssembler ma = (TileMolecularAssembler) te; + ma.setAnimationStatus(new AssemblerAnimationStatus(rate, is.asItemStackRepresentation())); + } } } diff --git a/src/main/java/appeng/entity/EntityFloatingItem.java b/src/main/java/appeng/entity/EntityFloatingItem.java deleted file mode 100644 index 81ceea95d..000000000 --- a/src/main/java/appeng/entity/EntityFloatingItem.java +++ /dev/null @@ -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 . - */ - -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 TYPE; - - private ICanDie parent; - private int superDeath = 0; - private float progress = 0; - - public EntityFloatingItem(EntityType 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; - } -} diff --git a/src/main/java/appeng/entity/RenderFloatingItem.java b/src/main/java/appeng/entity/RenderFloatingItem.java deleted file mode 100644 index 7ef0ac69b..000000000 --- a/src/main/java/appeng/entity/RenderFloatingItem.java +++ /dev/null @@ -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 . - */ - -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; - } -} diff --git a/src/main/java/appeng/tile/crafting/AssemblerAnimationStatus.java b/src/main/java/appeng/tile/crafting/AssemblerAnimationStatus.java new file mode 100644 index 000000000..35cd248df --- /dev/null +++ b/src/main/java/appeng/tile/crafting/AssemblerAnimationStatus.java @@ -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; + } +} diff --git a/src/main/java/appeng/tile/crafting/MolecularAssemblerRenderer.java b/src/main/java/appeng/tile/crafting/MolecularAssemblerRenderer.java new file mode 100644 index 000000000..128ce02af --- /dev/null +++ b/src/main/java/appeng/tile/crafting/MolecularAssemblerRenderer.java @@ -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 . + */ + +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 { + + 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); + } + +} diff --git a/src/main/java/appeng/tile/crafting/TileMolecularAssembler.java b/src/main/java/appeng/tile/crafting/TileMolecularAssembler.java index 2bf391de9..07b73a8a4 100644 --- a/src/main/java/appeng/tile/crafting/TileMolecularAssembler.java +++ b/src/main/java/appeng/tile/crafting/TileMolecularAssembler.java @@ -31,6 +31,8 @@ import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; 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.items.IItemHandler; @@ -77,6 +79,8 @@ import appeng.util.inv.WrapperFilteredItemHandler; import appeng.util.inv.filter.IAEItemFilter; import appeng.util.item.AEItemStack; +import javax.annotation.Nullable; + public class TileMolecularAssembler extends AENetworkInvTile implements IUpgradeableHost, IConfigManagerHost, IGridTickable, ICraftingMachine, IPowerChannelState { @@ -98,6 +102,9 @@ public class TileMolecularAssembler extends AENetworkInvTile private boolean forcePlan = false; private boolean reboot = true; + @OnlyIn(Dist.CLIENT) + private AssemblerAnimationStatus animationStatus; + public TileMolecularAssembler(TileEntityType tileEntityTypeIn) { super(tileEntityTypeIn); final ITileDefinition assembler = AEApi.instance().definitions().blocks().molecularAssembler(); @@ -417,11 +424,13 @@ public class TileMolecularAssembler extends AENetworkInvTile 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); - NetworkHandler.instance().sendToAllAround(new PacketAssemblerAnimation(this.pos, (byte) speed, item), - where); + if (item != null) { + 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.updateSleepiness(); @@ -533,6 +542,17 @@ public class TileMolecularAssembler extends AENetworkInvTile 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 boolean hasPattern() { return TileMolecularAssembler.this.myPlan != null diff --git a/src/main/resources/assets/appliedenergistics2/blockstates/molecular_assembler.json b/src/main/resources/assets/appliedenergistics2/blockstates/molecular_assembler.json index 63a54e468..2ee5c3f8d 100644 --- a/src/main/resources/assets/appliedenergistics2/blockstates/molecular_assembler.json +++ b/src/main/resources/assets/appliedenergistics2/blockstates/molecular_assembler.json @@ -1,17 +1,7 @@ { - "multipart": [ - { - "apply": { - "model": "appliedenergistics2:block/molecular_assembler" - } - }, - { - "when": { - "powered": "true" - }, - "apply": { - "model": "appliedenergistics2:block/molecular_assembler_lights" - } + "variants": { + "": { + "model": "appliedenergistics2:block/molecular_assembler" } - ] + } } diff --git a/src/main/resources/assets/appliedenergistics2/particles/assembler_fx.json b/src/main/resources/assets/appliedenergistics2/particles/assembler_fx.json index 0967ef424..c7ff44a07 100644 --- a/src/main/resources/assets/appliedenergistics2/particles/assembler_fx.json +++ b/src/main/resources/assets/appliedenergistics2/particles/assembler_fx.json @@ -1 +1,3 @@ -{} +{ + "textures": [] +} diff --git a/src/main/resources/assets/appliedenergistics2/particles/crafting_fx.json b/src/main/resources/assets/appliedenergistics2/particles/crafting_fx.json index 26dbb39df..e85de8b47 100644 --- a/src/main/resources/assets/appliedenergistics2/particles/crafting_fx.json +++ b/src/main/resources/assets/appliedenergistics2/particles/crafting_fx.json @@ -1,3 +1,3 @@ { - "textures": ["appliedenergistics2:particles/energy"] + "textures": ["appliedenergistics2:energy"] } diff --git a/src/main/resources/assets/appliedenergistics2/particles/energy_fx.json b/src/main/resources/assets/appliedenergistics2/particles/energy_fx.json new file mode 100644 index 000000000..c7ff44a07 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/particles/energy_fx.json @@ -0,0 +1,3 @@ +{ + "textures": [] +} diff --git a/src/main/resources/assets/appliedenergistics2/particles/matter_cannon_fx.json b/src/main/resources/assets/appliedenergistics2/particles/matter_cannon_fx.json index f0a4e5277..8d247c4a5 100644 --- a/src/main/resources/assets/appliedenergistics2/particles/matter_cannon_fx.json +++ b/src/main/resources/assets/appliedenergistics2/particles/matter_cannon_fx.json @@ -1,3 +1,3 @@ { - "textures": ["appliedenergistics2:particles/matter_cannon"] + "textures": ["appliedenergistics2:matter_cannon"] } diff --git a/src/main/resources/assets/appliedenergistics2/textures/particles/energy.png b/src/main/resources/assets/appliedenergistics2/textures/particle/energy.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/particles/energy.png rename to src/main/resources/assets/appliedenergistics2/textures/particle/energy.png diff --git a/src/main/resources/assets/appliedenergistics2/textures/particles/matter_cannon.png b/src/main/resources/assets/appliedenergistics2/textures/particle/matter_cannon.png similarity index 100% rename from src/main/resources/assets/appliedenergistics2/textures/particles/matter_cannon.png rename to src/main/resources/assets/appliedenergistics2/textures/particle/matter_cannon.png