mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-14 23:23:42 +01:00
more changes to heater and particles
-heater now uses a enum for the blaze state -added new particles for the heater -changed heaters voxel shape
This commit is contained in:
parent
e7a851c8c0
commit
b2a5a4822a
13 changed files with 510 additions and 110 deletions
|
@ -69,6 +69,10 @@ minecraft {
|
|||
}
|
||||
}
|
||||
|
||||
compileJava {
|
||||
options.compilerArgs = ["-Xdiags:verbose"]
|
||||
}
|
||||
|
||||
sourceSets.main.resources {
|
||||
srcDir 'src/generated/resources'
|
||||
}
|
||||
|
|
|
@ -2,13 +2,11 @@ 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.content.contraptions.particle.*;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.particle.IParticleFactory;
|
||||
import net.minecraft.client.particle.ParticleManager;
|
||||
import net.minecraft.particles.IParticleData;
|
||||
import net.minecraft.particles.ParticleType;
|
||||
|
@ -23,15 +21,21 @@ public enum AllParticleTypes {
|
|||
|
||||
ROTATION_INDICATOR(RotationIndicatorParticleData::new),
|
||||
AIR_FLOW(AirFlowParticleData::new),
|
||||
HEATER_PARTICLE(HeaterParticleData::new)
|
||||
HEATER_PARTICLE(HeaterParticleData::new),
|
||||
CUBE(CubeParticleData::dummy, CubeParticle.Factory::new)
|
||||
|
||||
;
|
||||
|
||||
private ParticleEntry<?> entry;
|
||||
|
||||
private <D extends IParticleData> AllParticleTypes(Supplier<? extends ICustomParticle<D>> typeFactory) {
|
||||
<D extends IParticleData> AllParticleTypes(Supplier<? extends ICustomParticle<D>> typeFactory) {
|
||||
String asId = Lang.asId(this.name());
|
||||
entry = new ParticleEntry<D>(new ResourceLocation(Create.ID, asId), typeFactory);
|
||||
entry = new ParticleEntry<>(new ResourceLocation(Create.ID, asId), typeFactory);
|
||||
}
|
||||
|
||||
<D extends IParticleData> AllParticleTypes(Supplier<? extends ICustomParticle<D>> typeFactory, Supplier<IParticleFactory<D>> particleMetaFactory) {
|
||||
String asId = Lang.asId(this.name());
|
||||
entry = new ParticleEntry<>(new ResourceLocation(Create.ID, asId), typeFactory, particleMetaFactory);
|
||||
}
|
||||
|
||||
public static void register(RegistryEvent.Register<ParticleType<?>> event) {
|
||||
|
@ -56,12 +60,18 @@ public enum AllParticleTypes {
|
|||
|
||||
private class ParticleEntry<D extends IParticleData> {
|
||||
Supplier<? extends ICustomParticle<D>> typeFactory;
|
||||
Supplier<IParticleFactory<D>> particleMetaFactory;
|
||||
ParticleType<D> type;
|
||||
ResourceLocation id;
|
||||
|
||||
public ParticleEntry(ResourceLocation id, Supplier<? extends ICustomParticle<D>> typeFactory) {
|
||||
public ParticleEntry(ResourceLocation id, Supplier<? extends ICustomParticle<D>> typeFactory, Supplier<IParticleFactory<D>> particleMetaFactory) {
|
||||
this.id = id;
|
||||
this.typeFactory = typeFactory;
|
||||
this.particleMetaFactory = particleMetaFactory;
|
||||
}
|
||||
|
||||
public ParticleEntry(ResourceLocation id, Supplier<? extends ICustomParticle<D>> typeFactory) {
|
||||
this(id, typeFactory, null);
|
||||
}
|
||||
|
||||
ParticleType<?> getType() {
|
||||
|
@ -85,8 +95,10 @@ public enum AllParticleTypes {
|
|||
@OnlyIn(Dist.CLIENT)
|
||||
void registerFactory(ParticleManager particles) {
|
||||
makeType();
|
||||
particles.registerFactory(type, typeFactory.get()
|
||||
.getFactory());
|
||||
if (particleMetaFactory == null)
|
||||
particles.registerFactory(type, typeFactory.get().getFactory());
|
||||
else
|
||||
particles.registerFactory(type, particleMetaFactory.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -113,11 +113,11 @@ public class AllShapes {
|
|||
|
||||
BASIN_BLOCK_SHAPE = shape(0, 2, 0, 16, 13, 16).erase(2, 5, 2, 14, 14, 14)
|
||||
.add(2, 0, 2, 14, 2, 14)
|
||||
.build(),
|
||||
.build(),
|
||||
HEATER_BLOCK_SHAPE =
|
||||
shape(2, 0, 2, 14, 16, 14).add(0, 0, 0, 16, 2, 16)
|
||||
.erase(3, 5, 3, 13, 16, 13)
|
||||
.build(),
|
||||
shape(2, 0, 2, 14, 14, 14).add(0, 0, 0, 16, 4, 16).build(),
|
||||
HEATER_BLOCK_SPECIAL_COLLISION_SHAPE =
|
||||
shape(0, 0, 0, 16, 4, 16).build(),
|
||||
CRUSHING_WHEEL_COLLISION_SHAPE = cuboid(0, 0, 0, 16, 22, 16),
|
||||
MECHANICAL_PROCESSOR_SHAPE = shape(VoxelShapes.fullCube()).erase(4, 0, 4, 12, 16, 12)
|
||||
.build(),
|
||||
|
|
|
@ -162,6 +162,7 @@ public class CreateJEI implements IModPlugin {
|
|||
registration.addRecipeCatalyst(new ItemStack(AllItems.BLOCKZAPPER.get()), blockzapperCategory.getUid());
|
||||
registration.addRecipeCatalyst(new ItemStack(AllBlocks.MECHANICAL_MIXER.get()), mixingCategory.getUid());
|
||||
registration.addRecipeCatalyst(new ItemStack(AllBlocks.BASIN.get()), mixingCategory.getUid());
|
||||
registration.addRecipeCatalyst(new ItemStack(AllBlocks.HEATER.get()), mixingCategory.getUid());
|
||||
registration.addRecipeCatalyst(new ItemStack(AllBlocks.MECHANICAL_SAW.get()), sawingCategory.getUid());
|
||||
registration.addRecipeCatalyst(new ItemStack(AllBlocks.MECHANICAL_SAW.get()), blockCuttingCategory.getUid());
|
||||
registration.addRecipeCatalyst(new ItemStack(Blocks.STONECUTTER), blockCuttingCategory.getUid());
|
||||
|
|
|
@ -6,9 +6,7 @@ import com.simibubi.create.content.contraptions.processing.HeaterBlock;
|
|||
import com.simibubi.create.content.logistics.block.chute.ChuteTileEntity;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.config.CKinetics;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.CampfireBlock;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
@ -78,9 +76,17 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity {
|
|||
if (world == null)
|
||||
return false;
|
||||
BlockState checkState = world.getBlockState(pos.down());
|
||||
return checkState.getBlock().isIn(AllBlockTags.FAN_HEATERS.tag)
|
||||
&& ((!checkState.has(HeaterBlock.BLAZE_LEVEL)) || checkState.get(HeaterBlock.BLAZE_LEVEL) >= 1)
|
||||
&& (!checkState.has(BlockStateProperties.LIT) || checkState.get(BlockStateProperties.LIT));
|
||||
|
||||
if (!checkState.getBlock().isIn(AllBlockTags.FAN_HEATERS.tag))
|
||||
return false;
|
||||
|
||||
if (checkState.has(HeaterBlock.BLAZE_LEVEL) && !checkState.get(HeaterBlock.BLAZE_LEVEL).min(HeaterBlock.HeatLevel.FADING))
|
||||
return false;
|
||||
|
||||
if (checkState.has(BlockStateProperties.LIT) && !checkState.get(BlockStateProperties.LIT))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public float getMaxDistance() {
|
||||
|
|
|
@ -232,7 +232,7 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
|
|||
|
||||
if (!(recipe instanceof MixingRecipe))
|
||||
return true;
|
||||
return ((MixingRecipe) recipe).getHeatLevelRequired() <= getHeatLevelApplied();
|
||||
return ((MixingRecipe) recipe).getHeatLevelRequired() <= getHeatLevelApplied().ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -269,12 +269,12 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
|
|||
return running;
|
||||
}
|
||||
|
||||
private int getHeatLevelApplied() {
|
||||
private HeaterBlock.HeatLevel getHeatLevelApplied() {
|
||||
if (world == null)
|
||||
return 0;
|
||||
return HeaterBlock.HeatLevel.NONE;
|
||||
BlockState state = world.getBlockState(pos.down(3));
|
||||
if (state.has(HeaterBlock.BLAZE_LEVEL))
|
||||
return state.get(HeaterBlock.BLAZE_LEVEL);
|
||||
return AllTags.AllBlockTags.FAN_HEATERS.matches(state) ? 1 : 0;
|
||||
return AllTags.AllBlockTags.FAN_HEATERS.matches(state) ? HeaterBlock.HeatLevel.SMOULDERING : HeaterBlock.HeatLevel.NONE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
package com.simibubi.create.content.contraptions.particle;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
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.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class CubeParticle extends Particle {
|
||||
|
||||
public static final Vec3d[] CUBE = {
|
||||
// TOP
|
||||
new Vec3d(1, 1, -1), new Vec3d(1, 1, 1), new Vec3d(-1, 1, 1), new Vec3d(-1, 1, -1),
|
||||
|
||||
// BOTTOM
|
||||
new Vec3d(-1, -1, -1), new Vec3d(-1, -1, 1), new Vec3d(1, -1, 1), new Vec3d(1, -1, -1),
|
||||
|
||||
// FRONT
|
||||
new Vec3d(-1, -1, 1), new Vec3d(-1, 1, 1), new Vec3d(1, 1, 1), new Vec3d(1, -1, 1),
|
||||
|
||||
// BACK
|
||||
new Vec3d(1, -1, -1), new Vec3d(1, 1, -1), new Vec3d(-1, 1, -1), new Vec3d(-1, -1, -1),
|
||||
|
||||
// LEFT
|
||||
new Vec3d(-1, -1, -1), new Vec3d(-1, 1, -1), new Vec3d(-1, 1, 1), new Vec3d(-1, -1, 1),
|
||||
|
||||
// RIGHT
|
||||
new Vec3d(1, -1, 1), new Vec3d(1, 1, 1), new Vec3d(1, 1, -1), new Vec3d(1, -1, -1) };
|
||||
|
||||
public static final Vec3d[] CUBE_NORMALS = {
|
||||
//modified normals for the sides
|
||||
new Vec3d(0, 1, 0),
|
||||
new Vec3d(0, -1, 0),
|
||||
new Vec3d(0, 0, 1),
|
||||
new Vec3d(0, 0, 1),
|
||||
new Vec3d(0, 0, 1),
|
||||
new Vec3d(0, 0, 1),
|
||||
|
||||
|
||||
/*new Vec3d(0, 1, 0),
|
||||
new Vec3d(0, -1, 0),
|
||||
new Vec3d(0, 0, 1),
|
||||
new Vec3d(0, 0, -1),
|
||||
new Vec3d(-1, 0, 0),
|
||||
new Vec3d(1, 0, 0)*/
|
||||
};
|
||||
|
||||
private static final IParticleRenderType renderType = new IParticleRenderType() {
|
||||
@Override
|
||||
public void beginRender(BufferBuilder builder, TextureManager textureManager) {
|
||||
RenderSystem.disableTexture();
|
||||
|
||||
//transparent, additive blending
|
||||
//RenderSystem.depthMask(false);
|
||||
//RenderSystem.enableBlend();
|
||||
//RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE);
|
||||
//RenderSystem.enableLighting();
|
||||
|
||||
//opaque
|
||||
RenderSystem.depthMask(true);
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.enableLighting();
|
||||
|
||||
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishRender(Tessellator tessellator) {
|
||||
tessellator.draw();
|
||||
RenderSystem.enableTexture();
|
||||
}
|
||||
};
|
||||
|
||||
protected float scale;
|
||||
|
||||
public CubeParticle(World world, double x, double y, double z, double motionX, double motionY, double motionZ) {
|
||||
super(world, x, y, z);
|
||||
this.motionX = motionX;
|
||||
this.motionY = motionY;
|
||||
this.motionZ = motionZ;
|
||||
|
||||
setScale(0.2F);
|
||||
}
|
||||
|
||||
public void setScale(float scale) {
|
||||
this.scale = scale;
|
||||
this.setSize(scale, scale);
|
||||
}
|
||||
|
||||
public void averageAge(int age) {
|
||||
this.maxAge = (int) (age + (rand.nextDouble() * 2D - 1D) * 8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildGeometry(IVertexBuilder builder, ActiveRenderInfo renderInfo, float p_225606_3_) {
|
||||
Vec3d projectedView = renderInfo.getProjectedView();
|
||||
float lerpedX = (float)(MathHelper.lerp(p_225606_3_, this.prevPosX, this.posX) - projectedView.getX());
|
||||
float lerpedY = (float)(MathHelper.lerp(p_225606_3_, this.prevPosY, this.posY) - projectedView.getY());
|
||||
float lerpedZ = (float)(MathHelper.lerp(p_225606_3_, this.prevPosZ, this.posZ) - projectedView.getZ());
|
||||
|
||||
//int light = getBrightnessForRender(p_225606_3_);
|
||||
int light = 15728880;//15<<20 && 15<<4
|
||||
double ageMultiplier = 1 - Math.pow(age, 3) / Math.pow(maxAge, 3);
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
//6 faces to a cube
|
||||
for (int j = 0; j < 4; j++) {
|
||||
Vec3d vec = CUBE[i * 4 + j];
|
||||
vec = vec
|
||||
/*.rotate(?)*/
|
||||
.scale(scale * ageMultiplier)
|
||||
.add(lerpedX, lerpedY, lerpedZ);
|
||||
|
||||
Vec3d normal = CUBE_NORMALS[i];
|
||||
builder.vertex(vec.x, vec.y, vec.z).color(particleRed, particleGreen, particleBlue, particleAlpha).texture(0,0).light(light).normal((float)normal.x,(float) normal.y,(float) normal.z).endVertex();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IParticleRenderType getRenderType() {
|
||||
return renderType;
|
||||
}
|
||||
|
||||
public static class Factory implements IParticleFactory<CubeParticleData> {
|
||||
|
||||
public Factory() {}
|
||||
|
||||
@Override
|
||||
public Particle makeParticle(CubeParticleData data, World world, double x, double y, double z, double motionX, double motionY, double motionZ) {
|
||||
CubeParticle particle = new CubeParticle(world, x, y, z, motionX, motionY, motionZ);
|
||||
particle.setColor(data.r, data.g, data.b);
|
||||
particle.setScale(data.scale);
|
||||
particle.averageAge(data.avgAge);
|
||||
return particle;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package com.simibubi.create.content.contraptions.particle;
|
||||
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.simibubi.create.AllParticleTypes;
|
||||
import net.minecraft.client.particle.ParticleManager;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.particles.IParticleData;
|
||||
import net.minecraft.particles.ParticleType;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class CubeParticleData implements IParticleData, ICustomParticle<CubeParticleData> {
|
||||
|
||||
public static final IParticleData.IDeserializer<CubeParticleData> DESERIALIZER = new IParticleData.IDeserializer<CubeParticleData>() {
|
||||
@Override
|
||||
public CubeParticleData deserialize(ParticleType<CubeParticleData> type, 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 scale = reader.readFloat();
|
||||
reader.expect(' ');
|
||||
int avgAge = reader.readInt();
|
||||
return new CubeParticleData(r, g, b, scale, avgAge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CubeParticleData read(ParticleType<CubeParticleData> type, PacketBuffer buffer) {
|
||||
return new CubeParticleData(buffer.readFloat(), buffer.readFloat(), buffer.readFloat(), buffer.readFloat(), buffer.readInt());
|
||||
}
|
||||
};
|
||||
|
||||
final float r;
|
||||
final float g;
|
||||
final float b;
|
||||
final float scale;
|
||||
final int avgAge;
|
||||
|
||||
public CubeParticleData(float r, float g, float b, float scale, int avgAge) {
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
this.scale = scale;
|
||||
this.avgAge = avgAge;
|
||||
}
|
||||
|
||||
public static CubeParticleData dummy() {
|
||||
return new CubeParticleData(0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDeserializer<CubeParticleData> getDeserializer() {
|
||||
return DESERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParticleManager.IParticleMetaFactory<CubeParticleData> getFactory() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParticleType<?> getType() {
|
||||
return AllParticleTypes.CUBE.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketBuffer buffer) {
|
||||
buffer.writeFloat(r);
|
||||
buffer.writeFloat(g);
|
||||
buffer.writeFloat(b);
|
||||
buffer.writeFloat(scale);
|
||||
buffer.writeInt(avgAge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameters() {
|
||||
return String.format(Locale.ROOT, "%s %f %f %f %f %d", AllParticleTypes.CUBE.parameter(), r, g, b, scale, avgAge);
|
||||
}
|
||||
}
|
|
@ -7,18 +7,20 @@ import com.simibubi.create.AllShapes;
|
|||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.state.EnumProperty;
|
||||
import net.minecraft.state.IProperty;
|
||||
import net.minecraft.state.IntegerProperty;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
@ -31,11 +33,12 @@ import net.minecraft.world.World;
|
|||
@ParametersAreNonnullByDefault
|
||||
public class HeaterBlock extends Block implements ITE<HeaterTileEntity> {
|
||||
|
||||
public static IProperty<Integer> BLAZE_LEVEL = IntegerProperty.create("blaze_level", 0, 4);
|
||||
//public static IProperty<Integer> BLAZE_LEVEL = IntegerProperty.create("blaze_level", 0, 4);
|
||||
public static IProperty<HeatLevel> BLAZE_LEVEL = EnumProperty.create("blaze", HeatLevel.class);
|
||||
|
||||
public HeaterBlock(Properties properties) {
|
||||
super(properties);
|
||||
setDefaultState(super.getDefaultState().with(BLAZE_LEVEL, 0));
|
||||
setDefaultState(super.getDefaultState().with(BLAZE_LEVEL, HeatLevel.NONE));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -46,7 +49,7 @@ public class HeaterBlock extends Block implements ITE<HeaterTileEntity> {
|
|||
|
||||
@Override
|
||||
public boolean hasTileEntity(BlockState state) {
|
||||
return state.get(BLAZE_LEVEL) >= 1;
|
||||
return state.get(BLAZE_LEVEL).min(HeatLevel.SMOULDERING);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -61,28 +64,36 @@ public class HeaterBlock extends Block implements ITE<HeaterTileEntity> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand,
|
||||
BlockRayTraceResult blockRayTraceResult) {
|
||||
public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult blockRayTraceResult) {
|
||||
if (!hasTileEntity(state))
|
||||
return ActionResultType.PASS;
|
||||
|
||||
TileEntity te = world.getTileEntity(pos);
|
||||
if (te instanceof HeaterTileEntity && ((HeaterTileEntity) te).tryUpdateFuel(player.getHeldItem(hand), player)) {
|
||||
if (!player.isCreative())
|
||||
player.getHeldItem(hand)
|
||||
.shrink(1);
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
return ActionResultType.PASS;
|
||||
if (!(te instanceof HeaterTileEntity))
|
||||
return ActionResultType.PASS;
|
||||
|
||||
if (!((HeaterTileEntity) te).tryUpdateFuel(player.getHeldItem(hand), player))
|
||||
return ActionResultType.PASS;
|
||||
|
||||
if (!player.isCreative())
|
||||
player.getHeldItem(hand).shrink(1);
|
||||
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
||||
ItemStack item = context.getItem();
|
||||
BlockState state = super.getStateForPlacement(context);
|
||||
return (state != null ? state : getDefaultState()).with(BLAZE_LEVEL,
|
||||
(item.hasTag() && item.getTag() != null && item.getTag()
|
||||
.contains("has_blaze") && item.getTag()
|
||||
.getBoolean("has_blaze")) ? 1 : 0);
|
||||
if (!context.getItem().hasTag())
|
||||
return getDefaultState();
|
||||
|
||||
CompoundNBT tag = context.getItem().getTag();
|
||||
if (!tag.contains("has_blaze"))
|
||||
return getDefaultState();
|
||||
|
||||
if (tag.getBoolean("has_blaze"))
|
||||
return getDefaultState().with(BLAZE_LEVEL, HeatLevel.SMOULDERING);
|
||||
|
||||
return getDefaultState();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -91,16 +102,43 @@ public class HeaterBlock extends Block implements ITE<HeaterTileEntity> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int getLightValue(BlockState state, IBlockReader world, BlockPos pos) {
|
||||
return MathHelper.clamp(state.get(BLAZE_LEVEL) * 4 - 1, 0, 15);
|
||||
public VoxelShape getCollisionShape(BlockState p_220071_1_, IBlockReader p_220071_2_, BlockPos p_220071_3_, ISelectionContext p_220071_4_) {
|
||||
if (p_220071_4_ == ISelectionContext.dummy())
|
||||
return AllShapes.HEATER_BLOCK_SPECIAL_COLLISION_SHAPE;
|
||||
|
||||
return super.getShape(p_220071_1_, p_220071_2_, p_220071_3_, p_220071_4_);
|
||||
}
|
||||
|
||||
static void setBlazeLevel(@Nullable World world, BlockPos pos, int blazeLevel) {
|
||||
@Override
|
||||
public int getLightValue(BlockState state, IBlockReader world, BlockPos pos) {
|
||||
return MathHelper.clamp(state.get(BLAZE_LEVEL).ordinal() * 4 - 1, 0, 15);
|
||||
}
|
||||
|
||||
static void setBlazeLevel(@Nullable World world, BlockPos pos, HeatLevel blazeLevel) {
|
||||
if (world != null)
|
||||
world.setBlockState(pos, world.getBlockState(pos).with(BLAZE_LEVEL, blazeLevel));
|
||||
}
|
||||
|
||||
public static int getHeaterLevel(BlockState blockState) {
|
||||
return blockState.has(HeaterBlock.BLAZE_LEVEL) ? blockState.get(HeaterBlock.BLAZE_LEVEL) : 0;
|
||||
public static HeatLevel getHeaterLevel(BlockState blockState) {
|
||||
return blockState.has(HeaterBlock.BLAZE_LEVEL) ? blockState.get(HeaterBlock.BLAZE_LEVEL) : HeatLevel.NONE;
|
||||
}
|
||||
|
||||
public enum HeatLevel implements IStringSerializable {
|
||||
NONE,
|
||||
SMOULDERING,
|
||||
FADING,
|
||||
KINDLED,
|
||||
SEETHING,
|
||||
//if you think you have better names let me know :)
|
||||
;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return Lang.asId(name());
|
||||
}
|
||||
|
||||
public boolean min(HeatLevel heatLevel) {
|
||||
return this.ordinal() >= heatLevel.ordinal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,13 +16,13 @@ import java.util.HashMap;
|
|||
|
||||
public class HeaterRenderer extends SafeTileEntityRenderer<HeaterTileEntity> {
|
||||
private static final Minecraft INSTANCE = Minecraft.getInstance();
|
||||
private static final HashMap<Integer, AllBlockPartials> blazeModelMap = new HashMap<>();
|
||||
private static final HashMap<HeaterBlock.HeatLevel, AllBlockPartials> blazeModelMap = new HashMap<>();
|
||||
|
||||
public HeaterRenderer(TileEntityRendererDispatcher dispatcher) {
|
||||
super(dispatcher);
|
||||
blazeModelMap.put(2, AllBlockPartials.BLAZE_HEATER_BLAZE_TWO);
|
||||
blazeModelMap.put(3, AllBlockPartials.BLAZE_HEATER_BLAZE_THREE);
|
||||
blazeModelMap.put(4, AllBlockPartials.BLAZE_HEATER_BLAZE_FOUR);
|
||||
blazeModelMap.put(HeaterBlock.HeatLevel.FADING, AllBlockPartials.BLAZE_HEATER_BLAZE_TWO);
|
||||
blazeModelMap.put(HeaterBlock.HeatLevel.KINDLED, AllBlockPartials.BLAZE_HEATER_BLAZE_THREE);
|
||||
blazeModelMap.put(HeaterBlock.HeatLevel.SEETHING, AllBlockPartials.BLAZE_HEATER_BLAZE_FOUR);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -5,56 +5,75 @@ 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.content.contraptions.particle.CubeParticleData;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.EggEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.particles.IParticleData;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import net.minecraftforge.event.entity.ProjectileImpactEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@Mod.EventBusSubscriber
|
||||
public class HeaterTileEntity extends SmartTileEntity {
|
||||
private int fuelLevel;
|
||||
private int burnTimeRemaining;
|
||||
|
||||
private final static int[][] heatParticleColors = {
|
||||
{0x3B141A, 0x47141A, 0x7A3B24, 0x854D26},
|
||||
{0x2A0103, 0x741B0A, 0xC38246, 0xCCBD78},
|
||||
{0x630B03, 0x8B3503, 0xBC8200, 0xCCC849},
|
||||
{0x1C6378, 0x4798B5, 0x4DA6C0, 0xBAC8CE}
|
||||
};
|
||||
|
||||
private static final int maxHeatCapacity = 10000;
|
||||
|
||||
private int remainingBurnTime;
|
||||
private FuelType activeFuel;
|
||||
|
||||
public HeaterTileEntity(TileEntityType<? extends HeaterTileEntity> tileEntityTypeIn) {
|
||||
super(tileEntityTypeIn);
|
||||
fuelLevel = 0;
|
||||
burnTimeRemaining = 0;
|
||||
setLazyTickRate(20);
|
||||
activeFuel = FuelType.NONE;
|
||||
remainingBurnTime = 0;
|
||||
setLazyTickRate(40);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (burnTimeRemaining > 0) {
|
||||
burnTimeRemaining--;
|
||||
if (burnTimeRemaining <= 0 && fuelLevel > 1) {
|
||||
fuelLevel--;
|
||||
burnTimeRemaining = maxHeatCapacity / 2;
|
||||
}
|
||||
updateHeatLevel();
|
||||
markDirty();
|
||||
|
||||
spawnParticles(getHeatLevel());
|
||||
|
||||
if (remainingBurnTime <= 0) {
|
||||
return;
|
||||
}
|
||||
remainingBurnTime--;
|
||||
if (remainingBurnTime == 0)
|
||||
if (activeFuel == FuelType.SPECIAL) {
|
||||
activeFuel = FuelType.NORMAL;
|
||||
remainingBurnTime = maxHeatCapacity / 2;
|
||||
updateHeatLevel();
|
||||
} else {
|
||||
activeFuel = FuelType.NONE;
|
||||
updateHeatLevel();
|
||||
}
|
||||
markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lazyTick() {
|
||||
super.lazyTick();
|
||||
spawnParticles(ParticleTypes.SMOKE);
|
||||
int heatLevel = getHeatLevel();
|
||||
if (heatLevel >= 2)
|
||||
spawnParticles(ParticleTypes.FLAME);
|
||||
if (heatLevel > 3) {
|
||||
spawnParticles(new HeaterParticleData(0.3f, 0.3f, 1f));
|
||||
}
|
||||
//using lazy ticks to transition between kindled and fading, this doesn't need to happen instantly at the threshold
|
||||
updateHeatLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -62,62 +81,148 @@ public class HeaterTileEntity extends SmartTileEntity {
|
|||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
compound.putInt("fuelLevel", fuelLevel);
|
||||
compound.putInt("burnTimeRemaining", burnTimeRemaining);
|
||||
compound.putInt("fuelLevel", activeFuel.ordinal());
|
||||
compound.putInt("burnTimeRemaining", remainingBurnTime);
|
||||
return super.write(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT compound) {
|
||||
fuelLevel = compound.getInt("fuelLevel");
|
||||
burnTimeRemaining = compound.getInt("burnTimeRemaining");
|
||||
activeFuel = FuelType.values()[compound.getInt("fuelLevel")];
|
||||
remainingBurnTime = compound.getInt("burnTimeRemaining");
|
||||
super.read(compound);
|
||||
if (fuelLevel == 0)
|
||||
burnTimeRemaining = 0;
|
||||
updateHeatLevel();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the heater updated its burn time and a item should be consumed
|
||||
*/
|
||||
boolean tryUpdateFuel(ItemStack itemStack, PlayerEntity player) {
|
||||
boolean specialFuelUsed = itemStack.getItem() == AllItems.FUEL_PELLET.get();
|
||||
int burnTime =
|
||||
itemStack.getItem() == Items.EGG ? 150 : (specialFuelUsed ? 1000 : ForgeHooks.getBurnTime(itemStack));
|
||||
int newFuelLevel = (specialFuelUsed ? 2 : 1);
|
||||
if (burnTime <= 0 || newFuelLevel < fuelLevel)
|
||||
return false;
|
||||
if (newFuelLevel > this.fuelLevel) {
|
||||
fuelLevel = newFuelLevel;
|
||||
burnTimeRemaining = burnTime;
|
||||
} else {
|
||||
if (burnTimeRemaining + burnTime > maxHeatCapacity && player instanceof DeployerFakePlayer)
|
||||
return false;
|
||||
burnTimeRemaining = MathHelper.clamp(burnTimeRemaining + burnTime, 0, maxHeatCapacity);
|
||||
FuelType newFuel = FuelType.NONE;
|
||||
int burnTick = ForgeHooks.getBurnTime(itemStack);
|
||||
if (burnTick > 0)
|
||||
newFuel = FuelType.NORMAL;
|
||||
if (itemStack.getItem() == AllItems.FUEL_PELLET.get()) {
|
||||
burnTick = 1000;
|
||||
newFuel = FuelType.SPECIAL;
|
||||
}
|
||||
|
||||
if (newFuel == FuelType.NONE || newFuel.ordinal() < activeFuel.ordinal())
|
||||
return false;
|
||||
|
||||
if (newFuel == activeFuel) {
|
||||
if (remainingBurnTime + burnTick > maxHeatCapacity && player instanceof DeployerFakePlayer)
|
||||
return false;
|
||||
|
||||
remainingBurnTime = MathHelper.clamp(remainingBurnTime + burnTick, 0, maxHeatCapacity);
|
||||
} else {
|
||||
activeFuel = newFuel;
|
||||
remainingBurnTime = burnTick;
|
||||
}
|
||||
|
||||
updateHeatLevel();
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getHeatLevel() {
|
||||
public HeaterBlock.HeatLevel getHeatLevel() {
|
||||
return HeaterBlock.getHeaterLevel(getBlockState());
|
||||
}
|
||||
|
||||
private void updateHeatLevel() {
|
||||
if (fuelLevel == 2)
|
||||
HeaterBlock.setBlazeLevel(world, pos, 4);
|
||||
else if (fuelLevel == 0 || burnTimeRemaining <= 0)
|
||||
HeaterBlock.setBlazeLevel(world, pos, 1);
|
||||
else {
|
||||
HeaterBlock.setBlazeLevel(world, pos, (double) burnTimeRemaining / maxHeatCapacity > 0.1 ? 3 : 2);
|
||||
switch (activeFuel) {
|
||||
case SPECIAL:
|
||||
HeaterBlock.setBlazeLevel(world, pos, HeaterBlock.HeatLevel.SEETHING);
|
||||
break;
|
||||
case NORMAL:
|
||||
boolean lowPercent = (double) remainingBurnTime / maxHeatCapacity < 0.1;
|
||||
HeaterBlock.setBlazeLevel(world, pos, lowPercent ? HeaterBlock.HeatLevel.FADING : HeaterBlock.HeatLevel.KINDLED);
|
||||
break;
|
||||
case NONE:
|
||||
HeaterBlock.setBlazeLevel(world, pos, HeaterBlock.HeatLevel.SMOULDERING);
|
||||
}
|
||||
}
|
||||
|
||||
private void spawnParticles(IParticleData basicparticletype) {
|
||||
private void spawnParticles(HeaterBlock.HeatLevel heatLevel) {
|
||||
if (world == null)
|
||||
return;
|
||||
|
||||
if (heatLevel == HeaterBlock.HeatLevel.NONE)
|
||||
return;
|
||||
|
||||
Random r = world.getRandom();
|
||||
if (heatLevel == HeaterBlock.HeatLevel.SMOULDERING) {
|
||||
if (r.nextDouble() > 0.25)
|
||||
return;
|
||||
|
||||
Vec3d color = randomColor(heatLevel);
|
||||
spawnParticle(new CubeParticleData((float) color.x,(float) color.y,(float) color.z, 0.03F, 15), 0.015, 0.1);
|
||||
} else if (heatLevel == HeaterBlock.HeatLevel.FADING) {
|
||||
if (r.nextDouble() > 0.5)
|
||||
return;
|
||||
|
||||
Vec3d color = randomColor(heatLevel);
|
||||
spawnParticle(new CubeParticleData((float) color.x,(float) color.y,(float) color.z, 0.035F, 18), 0.03, 0.15);
|
||||
} else if (heatLevel == HeaterBlock.HeatLevel.KINDLED) {
|
||||
Vec3d color = randomColor(heatLevel);
|
||||
spawnParticle(new CubeParticleData((float) color.x,(float) color.y,(float) color.z, 0.04F, 21), 0.05, 0.2);
|
||||
}else if (heatLevel == HeaterBlock.HeatLevel.SEETHING) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (r.nextDouble() > 0.6)
|
||||
return;
|
||||
Vec3d color = randomColor(heatLevel);
|
||||
spawnParticle(new CubeParticleData((float) color.x,(float) color.y,(float) color.z, 0.045F, 24), 0.06, 0.22);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void spawnParticle(IParticleData particleData, double speed, double spread) {
|
||||
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);
|
||||
|
||||
world.addOptionalParticle(
|
||||
particleData,
|
||||
(double) pos.getX() + 0.5D + (random.nextDouble() * 2.0 - 1D) * spread,
|
||||
(double) pos.getY() + 0.6D + random.nextDouble() / 10.0,
|
||||
(double) pos.getZ() + 0.5D + (random.nextDouble() * 2.0 - 1D) * spread,
|
||||
0.0D,
|
||||
speed,
|
||||
0.0D);
|
||||
}
|
||||
|
||||
private static Vec3d randomColor(HeaterBlock.HeatLevel heatLevel) {
|
||||
if (heatLevel == HeaterBlock.HeatLevel.NONE)
|
||||
return new Vec3d(0,0,0);
|
||||
|
||||
return ColorHelper.getRGB(heatParticleColors[heatLevel.ordinal()-1][(int) (Math.random()*4)]);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void eggsGetEaten(ProjectileImpactEvent.Throwable event) {
|
||||
if (!(event.getThrowable() instanceof EggEntity))
|
||||
return;
|
||||
|
||||
if (event.getRayTraceResult().getType() != RayTraceResult.Type.BLOCK)
|
||||
return;
|
||||
|
||||
TileEntity tile = event.getThrowable().world.getTileEntity(new BlockPos(event.getRayTraceResult().getHitVec()));
|
||||
if (!(tile instanceof HeaterTileEntity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCanceled(true);
|
||||
event.getThrowable().setMotion(Vec3d.ZERO);
|
||||
event.getThrowable().remove();
|
||||
|
||||
HeaterTileEntity heater = (HeaterTileEntity) tile;
|
||||
if (heater.activeFuel != FuelType.SPECIAL)
|
||||
heater.activeFuel = FuelType.NORMAL;
|
||||
heater.remainingBurnTime = MathHelper.clamp(heater.remainingBurnTime + 80, 0, maxHeatCapacity);
|
||||
heater.markDirty();
|
||||
|
||||
}
|
||||
|
||||
private enum FuelType {
|
||||
NONE,
|
||||
NORMAL,
|
||||
SPECIAL
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import java.util.Optional;
|
|||
|
||||
import com.simibubi.create.AllRecipeTypes;
|
||||
import com.simibubi.create.content.contraptions.components.fan.SplashingRecipe;
|
||||
import com.simibubi.create.content.contraptions.processing.HeaterBlock;
|
||||
import com.simibubi.create.content.contraptions.processing.ProcessingRecipe;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
|
@ -62,9 +63,9 @@ public class InWorldProcessing {
|
|||
if (fluidState.getFluid() == Fluids.WATER || fluidState.getFluid() == Fluids.FLOWING_WATER)
|
||||
return Type.SPLASHING;
|
||||
if (blockState.getBlock() == Blocks.FIRE
|
||||
|| (blockState.getBlock() == Blocks.CAMPFIRE && blockState.get(CampfireBlock.LIT)) || getHeaterLevel(blockState) == 1)
|
||||
|| (blockState.getBlock() == Blocks.CAMPFIRE && blockState.get(CampfireBlock.LIT)) || getHeaterLevel(blockState) == HeaterBlock.HeatLevel.SMOULDERING)
|
||||
return Type.SMOKING;
|
||||
if (blockState.getBlock() == Blocks.LAVA || getHeaterLevel(blockState) >= 2)
|
||||
if (blockState.getBlock() == Blocks.LAVA || getHeaterLevel(blockState).min(HeaterBlock.HeatLevel.FADING))
|
||||
return Type.BLASTING;
|
||||
return null;
|
||||
}
|
||||
|
|
3
src/main/resources/assets/create/particles/cube.json
Normal file
3
src/main/resources/assets/create/particles/cube.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
|
||||
}
|
Loading…
Reference in a new issue