diff --git a/src/main/java/com/simibubi/create/AllParticleTypes.java b/src/main/java/com/simibubi/create/AllParticleTypes.java index 7df7d02b3..fbce493c2 100644 --- a/src/main/java/com/simibubi/create/AllParticleTypes.java +++ b/src/main/java/com/simibubi/create/AllParticleTypes.java @@ -3,6 +3,7 @@ package com.simibubi.create; import java.util.function.Supplier; import com.simibubi.create.content.contraptions.particle.AirFlowParticleData; +import com.simibubi.create.content.contraptions.particle.HeaterParticleData; import com.simibubi.create.content.contraptions.particle.ICustomParticle; import com.simibubi.create.content.contraptions.particle.RotationIndicatorParticleData; import com.simibubi.create.foundation.utility.Lang; @@ -22,6 +23,7 @@ public enum AllParticleTypes { ROTATION_INDICATOR(RotationIndicatorParticleData::new), AIR_FLOW(AirFlowParticleData::new), + HEATER_PARTICLE(HeaterParticleData::new) ; @@ -40,14 +42,14 @@ public enum AllParticleTypes { @OnlyIn(Dist.CLIENT) public static void registerFactories(ParticleFactoryRegisterEvent event) { ParticleManager particles = Minecraft.getInstance().particles; - for (AllParticleTypes particle : values()) + for (AllParticleTypes particle : values()) particle.entry.registerFactory(particles); } public ParticleType get() { return entry.getType(); } - + public String parameter() { return Lang.asId(name()); } @@ -74,7 +76,8 @@ public enum AllParticleTypes { void makeType() { if (type == null) { - type = typeFactory.get().createType(); + type = typeFactory.get() + .createType(); type.setRegistryName(id); } } @@ -82,7 +85,8 @@ public enum AllParticleTypes { @OnlyIn(Dist.CLIENT) void registerFactory(ParticleManager particles) { makeType(); - particles.registerFactory(type, typeFactory.get().getFactory()); + particles.registerFactory(type, typeFactory.get() + .getFactory()); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/particle/HeaterParticle.java b/src/main/java/com/simibubi/create/content/contraptions/particle/HeaterParticle.java new file mode 100644 index 000000000..1543ab12d --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/particle/HeaterParticle.java @@ -0,0 +1,110 @@ +package com.simibubi.create.content.contraptions.particle; + +import mcp.MethodsReturnNonnullByDefault; +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.particle.SimpleAnimatedParticle; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; + +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class HeaterParticle extends SimpleAnimatedParticle { + + private final IAnimatedSprite animatedSprite; + + public HeaterParticle(World worldIn, float r, float g, float b, double x, double y, double z, double vx, double vy, + double vz, IAnimatedSprite spriteSet) { + super(worldIn, x, y, z, spriteSet, worldIn.rand.nextFloat() * .5f); + + this.animatedSprite = spriteSet; + + this.motionX = this.motionX * (double) 0.01F + vx; + this.motionY = this.motionY * (double) 0.01F + vy; + this.motionZ = this.motionZ * (double) 0.01F + vz; + + this.particleRed = r; + this.particleGreen = g; + this.particleBlue = b; + + this.posX += (this.rand.nextFloat() - this.rand.nextFloat()) * 0.05F; + this.posY += (this.rand.nextFloat() - this.rand.nextFloat()) * 0.05F; + this.posZ += (this.rand.nextFloat() - this.rand.nextFloat()) * 0.05F; + + this.maxAge = (int) (8.0D / (Math.random() * 0.8D + 0.2D)) + 4; + this.particleScale *= 1.875F; + this.selectSpriteWithAge(animatedSprite); + + } + + @Override + public IParticleRenderType getRenderType() { + return IParticleRenderType.PARTICLE_SHEET_LIT; + } + + @Override + public float getScale(float p_217561_1_) { + float f = ((float) this.age + p_217561_1_) / (float) this.maxAge; + return this.particleScale * (1.0F - f * f * 0.5F); + } + + @Override + public void move(double x, double y, double z) { + this.setBoundingBox(this.getBoundingBox() + .offset(x, y, z)); + this.resetPositionToBB(); + } + + @Override + public int getBrightnessForRender(float p_189214_1_) { + float f = ((float) this.age + p_189214_1_) / (float) this.maxAge; + f = MathHelper.clamp(f, 0.0F, 1.0F); + int i = super.getBrightnessForRender(p_189214_1_); + int j = i & 255; + int k = i >> 16 & 255; + j = j + (int) (f * 15.0F * 16.0F); + if (j > 240) { + j = 240; + } + + return j | k << 16; + } + + @Override + public void tick() { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + if (this.age++ >= this.maxAge) { + this.setExpired(); + } else { + this.selectSpriteWithAge(animatedSprite); + this.move(this.motionX, this.motionY, this.motionZ); + this.motionX *= (double) 0.96F; + this.motionY *= (double) 0.96F; + this.motionZ *= (double) 0.96F; + if (this.onGround) { + this.motionX *= (double) 0.7F; + this.motionZ *= (double) 0.7F; + } + } + } + + public static class Factory implements IParticleFactory { + private final IAnimatedSprite spriteSet; + + public Factory(IAnimatedSprite animatedSprite) { + this.spriteSet = animatedSprite; + } + + @Override + public Particle makeParticle(HeaterParticleData data, World worldIn, double x, double y, double z, double vx, + double vy, double vz) { + return new HeaterParticle(worldIn, data.r, data.g, data.b, x, y, z, vx, vy, vz, this.spriteSet); + } + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/particle/HeaterParticleData.java b/src/main/java/com/simibubi/create/content/contraptions/particle/HeaterParticleData.java new file mode 100644 index 000000000..285ab6baf --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/particle/HeaterParticleData.java @@ -0,0 +1,81 @@ +package com.simibubi.create.content.contraptions.particle; + +import java.util.Locale; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.simibubi.create.AllParticleTypes; + +import mcp.MethodsReturnNonnullByDefault; +import net.minecraft.client.particle.ParticleManager.IParticleMetaFactory; +import net.minecraft.network.PacketBuffer; +import net.minecraft.particles.IParticleData; +import net.minecraft.particles.ParticleType; + +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class HeaterParticleData implements IParticleData, ICustomParticle { + public static final IParticleData.IDeserializer DESERIALIZER = + new IParticleData.IDeserializer() { + @Override + public HeaterParticleData deserialize(ParticleType arg0, StringReader reader) + throws CommandSyntaxException { + reader.expect(' '); + float r = reader.readFloat(); + reader.expect(' '); + float g = reader.readFloat(); + reader.expect(' '); + float b = reader.readFloat(); + return new HeaterParticleData(r, g, b); + } + + @Override + public HeaterParticleData read(ParticleType type, PacketBuffer buffer) { + return new HeaterParticleData(buffer.readFloat(), buffer.readFloat(), buffer.readFloat()); + } + }; + + final float r; + final float g; + final float b; + + public HeaterParticleData(float r, float g, float b) { + this.r = r; + this.g = g; + this.b = b; + } + + public HeaterParticleData() { + this(0, 0, 0); + } + + @Override + public IDeserializer getDeserializer() { + return DESERIALIZER; + } + + @Override + public IParticleMetaFactory getFactory() { + return HeaterParticle.Factory::new; + } + + @Override + public String getParameters() { + return String.format(Locale.ROOT, "%s %f %f %f", AllParticleTypes.HEATER_PARTICLE.parameter(), r, g, b); + } + + @Override + public ParticleType getType() { + return AllParticleTypes.HEATER_PARTICLE.get(); + } + + @Override + public void write(PacketBuffer buffer) { + buffer.writeFloat(r); + buffer.writeFloat(g); + buffer.writeFloat(b); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterTileEntity.java index 02f0f22b4..2aea9afb3 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterTileEntity.java @@ -1,9 +1,11 @@ package com.simibubi.create.content.contraptions.processing; import java.util.List; +import java.util.Random; import com.simibubi.create.AllItems; import com.simibubi.create.content.contraptions.components.deployer.DeployerFakePlayer; +import com.simibubi.create.content.contraptions.particle.HeaterParticleData; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; @@ -11,6 +13,8 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.nbt.CompoundNBT; +import net.minecraft.particles.IParticleData; +import net.minecraft.particles.ParticleTypes; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.math.MathHelper; import net.minecraftforge.common.ForgeHooks; @@ -24,7 +28,7 @@ public class HeaterTileEntity extends SmartTileEntity { super(tileEntityTypeIn); fuelLevel = 0; burnTimeRemaining = 0; - setLazyTickRate(40); + setLazyTickRate(20); } @Override @@ -44,7 +48,13 @@ public class HeaterTileEntity extends SmartTileEntity { @Override public void lazyTick() { super.lazyTick(); - updateHeatLevel(); + spawnParticles(ParticleTypes.SMOKE); + int heatLevel = getHeatLevel(); + if (heatLevel >= 2) + spawnParticles(ParticleTypes.FLAME); + if (heatLevel > 3) { + spawnParticles(new HeaterParticleData(0.3f, 0.3f, 1f)); + } } @Override @@ -99,4 +109,15 @@ public class HeaterTileEntity extends SmartTileEntity { HeaterBlock.setBlazeLevel(world, pos, (double) burnTimeRemaining / maxHeatCapacity > 0.1 ? 3 : 2); } } + + private void spawnParticles(IParticleData basicparticletype) { + if (world == null) + return; + Random random = world.getRandom(); + world.addOptionalParticle(basicparticletype, true, + (double) pos.getX() + 0.5D + random.nextDouble() / 3.0D * (double) (random.nextBoolean() ? 1 : -1), + (double) pos.getY() + random.nextDouble() + random.nextDouble(), + (double) pos.getZ() + 0.5D + random.nextDouble() / 3.0D * (double) (random.nextBoolean() ? 1 : -1), 0.0D, + 0.07D, 0.0D); + } } diff --git a/src/main/resources/assets/create/particles/heater_particle.json b/src/main/resources/assets/create/particles/heater_particle.json new file mode 100644 index 000000000..f3ae8cda7 --- /dev/null +++ b/src/main/resources/assets/create/particles/heater_particle.json @@ -0,0 +1,5 @@ +{ + "textures": [ + "minecraft:flame" + ] +}