Merge pull request #197 from Daniel366Cobra/qol-tweaks-exhaust

Fix exhaust and flarestack behavior
This commit is contained in:
PouffyDev
2025-07-12 23:43:20 +01:00
committed by GitHub
3 changed files with 184 additions and 274 deletions

View File

@@ -1,7 +1,6 @@
package com.drmangotea.tfmg.content.machinery.misc.exhaust;
import com.drmangotea.tfmg.base.TFMGUtils;
import com.drmangotea.tfmg.registry.TFMGFluids;
import com.simibubi.create.Create;
@@ -9,9 +8,6 @@ import com.simibubi.create.api.equipment.goggles.IHaveGoggleInformation;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.fluid.SmartFluidTank;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
@@ -24,14 +20,12 @@ import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidTank;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.templates.FluidTank;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Optional;
import java.util.Random;
@SuppressWarnings("removal")
@@ -40,27 +34,15 @@ public class ExhaustBlockEntity extends SmartBlockEntity implements IHaveGoggleI
protected LazyOptional<IFluidHandler> fluidCapability;
public FluidTank tankInventory;
public boolean spawnsSmoke=false;
public int smokeTimer=0;
public int smokeTimer = 0;
public ExhaustBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
tankInventory = createInventory();
fluidCapability = LazyOptional.of(() -> tankInventory);
}
@Override
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
return TFMGUtils.createFluidTooltip(this, tooltip);
}
protected SmartFluidTank createInventory() {
return new SmartFluidTank(1000, this::onFluidStackChanged) {
@Override
@@ -70,104 +52,6 @@ public class ExhaustBlockEntity extends SmartBlockEntity implements IHaveGoggleI
};
}
protected void onFluidStackChanged(FluidStack newFluidStack) {
sendData();
setChanged();
}
@Override
public void tick() {
super.tick();
Direction direction = this.getBlockState().getValue(ExhaustBlock.FACING);
if(smokeTimer!=0) {
spawnsSmoke = true;
smokeTimer--;
}else spawnsSmoke = false;
if (direction == Direction.UP)
if(spawnsSmoke)
makeParticles(level, this.getBlockPos(), 0);
if (direction == Direction.DOWN)
if(spawnsSmoke)
makeParticles(level, this.getBlockPos(), 1);
if (direction == Direction.NORTH)
if(spawnsSmoke)
makeParticles(level, this.getBlockPos(), 2);
if (direction == Direction.SOUTH)
if(spawnsSmoke)
makeParticles(level, this.getBlockPos(), 3);
if (direction == Direction.EAST)
if(spawnsSmoke)
makeParticles(level, this.getBlockPos(), 4);
if (direction == Direction.WEST)
if(spawnsSmoke)
makeParticles(level, this.getBlockPos(), 5);
if(tankInventory.getFluidAmount()>0) {
smokeTimer = 100;
spawnsSmoke = true;
}
if(tankInventory.getSpace()>700) {
tankInventory.drain(100, IFluidHandler.FluidAction.EXECUTE);
}else tankInventory.drain(10, IFluidHandler.FluidAction.EXECUTE);
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
tankInventory.readFromNBT(compound.getCompound("TankContent"));
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
compound.put("TankContent", tankInventory.writeToNBT(new CompoundTag()));
compound.putBoolean("Active", smokeTimer>0);
}
public static void makeParticles(Level level, BlockPos pos, int particleRotation) {
Random random = Create.RANDOM;
int shouldSpawnSmoke = random.nextInt(7);
if(shouldSpawnSmoke==0) {
if(particleRotation==0)
level.addParticle(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, pos.getX() +random.nextFloat(1), pos.getY() + 1, pos.getZ() +random.nextFloat(1), 0.0D, 0.08D, 0.0D);
if(particleRotation==1)
level.addParticle(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, pos.getX() +random.nextFloat(1), pos.getY(), pos.getZ() +random.nextFloat(1), 0.0D, 0.08D, 0.0D);
if(particleRotation==2)
level.addParticle(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, pos.getX() +random.nextFloat(1), pos.getY() +random.nextFloat(1), pos.getZ(), 0.0D, 0.08D, 0.0D);
if(particleRotation==3)
level.addParticle(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, pos.getX() +random.nextFloat(1), pos.getY() +random.nextFloat(1), pos.getZ() + 1, 0.0D, 0.08D, 0.0D);
if(particleRotation==4)
level.addParticle(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, pos.getX() + 1, pos.getY() +random.nextFloat(1), pos.getZ() +random.nextFloat(1), 0.0D, 0.08D, 0.0D);
if(particleRotation==5)
level.addParticle(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, pos.getX(), pos.getY() +random.nextFloat(1), pos.getZ() +random.nextFloat(1), 0.0D, 0.08D, 0.0D);
}
}
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
@@ -177,12 +61,83 @@ public class ExhaustBlockEntity extends SmartBlockEntity implements IHaveGoggleI
return super.getCapability(cap, side);
}
@Override
public void invalidate() {
super.invalidate();
fluidCapability.invalidate();
}
protected void onFluidStackChanged(FluidStack newFluidStack) {
if (!hasLevel()) return;
setChanged();
sendData();
}
@Override
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
return TFMGUtils.createFluidTooltip(this, tooltip);
}
@Override
public void tick() {
super.tick();
if (tankInventory.isEmpty()) return;
Direction direction = this.getBlockState().getValue(ExhaustBlock.FACING);
float fillRatio = (float) tankInventory.getFluidAmount() / tankInventory.getCapacity();
// Dynamic drain rate: 10mB/t (empty) → 50mB/t (full)
int drainRate = 10 + (int) (40 * fillRatio);
if (tankInventory.getFluidAmount() > 0) {
tankInventory.drain(drainRate, IFluidHandler.FluidAction.EXECUTE);
smokeTimer = 100;
}
if (smokeTimer > 0) {
smokeTimer--;
// Spawn particles every 1-10 ticks
if ((level.getGameTime() + getBlockPos().hashCode()) % Math.max(1, 10 - (int) (9 * fillRatio)) == 0) {
byte particleRotation = switch (direction) {
case DOWN -> 1;
case NORTH -> 2;
case SOUTH -> 3;
case EAST -> 4;
case WEST -> 5;
default -> 0;
};
makeParticles(level, getBlockPos(), particleRotation);
}
}
}
public static void makeParticles(Level level, BlockPos pos, int particleRotation) {
Random random = Create.RANDOM;
switch (particleRotation) {
case 1 -> level.addParticle(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, pos.getX() + random.nextFloat(1), pos.getY(), pos.getZ() + random.nextFloat(1), 0.0D, 0.08D, 0.0D);
case 2 -> level.addParticle(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, pos.getX() + random.nextFloat(1), pos.getY() + random.nextFloat(1), pos.getZ(), 0.0D, 0.08D, 0.0D);
case 3 -> level.addParticle(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, pos.getX() + random.nextFloat(1), pos.getY() + random.nextFloat(1), pos.getZ() + 1, 0.0D, 0.08D, 0.0D);
case 4 -> level.addParticle(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, pos.getX() + 1, pos.getY() + random.nextFloat(1), pos.getZ() + random.nextFloat(1), 0.0D, 0.08D, 0.0D);
case 5 -> level.addParticle(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, pos.getX(), pos.getY() + random.nextFloat(1), pos.getZ() + random.nextFloat(1), 0.0D, 0.08D, 0.0D);
default -> level.addParticle(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, pos.getX() + random.nextFloat(1), pos.getY() + 1, pos.getZ() + random.nextFloat(1), 0.0D, 0.08D, 0.0D);
}
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
tankInventory.readFromNBT(compound.getCompound("TankContent"));
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
compound.put("TankContent", tankInventory.writeToNBT(new CompoundTag()));
compound.putBoolean("Active", smokeTimer > 0);
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {}
}

View File

@@ -2,16 +2,12 @@ package com.drmangotea.tfmg.content.machinery.misc.flarestack;
import com.drmangotea.tfmg.base.TFMGUtils;
import com.drmangotea.tfmg.registry.TFMGFluids;
import com.drmangotea.tfmg.registry.TFMGTags;
import com.simibubi.create.Create;
import com.simibubi.create.api.equipment.goggles.IHaveGoggleInformation;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.fluid.SmartFluidTank;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
@@ -24,41 +20,26 @@ import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidTank;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.templates.FluidTank;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Optional;
import java.util.Random;
public class FlarestackBlockEntity extends SmartBlockEntity implements IHaveGoggleInformation {
protected LazyOptional<IFluidHandler> fluidCapability;
public FluidTank tankInventory;
public boolean spawnsSmoke=false;
public int smokeTimer=0;
public int smokeTimer = 0;
public FlarestackBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
tankInventory = createInventory();
fluidCapability = LazyOptional.of(() -> tankInventory);
}
@Override
@SuppressWarnings("removal")
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
return TFMGUtils.createFluidTooltip(this, tooltip);
}
protected SmartFluidTank createInventory() {
@@ -66,85 +47,11 @@ public class FlarestackBlockEntity extends SmartBlockEntity implements IHaveGogg
@Override
public boolean isFluidValid(FluidStack stack) {
return stack.getFluid().is(TFMGTags.TFMGFluidTags.FLAMMABLE.tag)||
stack.getFluid().is(TFMGTags.TFMGFluidTags.FUEL.tag);
stack.getFluid().is(TFMGTags.TFMGFluidTags.FUEL.tag);
}
};
}
protected void onFluidStackChanged(FluidStack newFluidStack) {
sendData();
setChanged();
}
@Override
public void tick() {
super.tick();
if(smokeTimer!=0) {
spawnsSmoke = true;
smokeTimer--;
}else {
spawnsSmoke = false;
}
if(spawnsSmoke) {
level.setBlock(getBlockPos(), this.getBlockState()
.setValue(FlarestackBlock.LIT, true), 2);
makeParticles(level, this.getBlockPos());
} else
{
level.setBlock(getBlockPos(), this.getBlockState()
.setValue(FlarestackBlock.LIT, false), 2);
}
if(tankInventory.getFluidAmount()>0) {
smokeTimer = 100;
spawnsSmoke = true;
if(tankInventory.getFluidAmount()>1000) {
tankInventory.drain(100, IFluidHandler.FluidAction.EXECUTE);
}else tankInventory.drain(30, IFluidHandler.FluidAction.EXECUTE);
}
}
public static void makeParticles(Level level, BlockPos pos) {
Random random = Create.RANDOM;
int shouldSpawnSmoke = random.nextInt(7);
if(shouldSpawnSmoke==0) {
level.addParticle(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, pos.getX() +random.nextFloat(1), pos.getY() + 1, pos.getZ() +random.nextFloat(1), 0.0D, 0.08D, 0.0D);
level.addParticle(ParticleTypes.FLAME, pos.getX() +random.nextFloat(1), pos.getY() + 1, pos.getZ() +random.nextFloat(1), Create.RANDOM.nextDouble(0.28)-0.14D, 0.14D, Create.RANDOM.nextDouble(0.28)-0.14D);
level.addParticle(ParticleTypes.FLAME, pos.getX() +random.nextFloat(1), pos.getY() + 1, pos.getZ() +random.nextFloat(1), Create.RANDOM.nextDouble(0.28)-0.14D, 0.14D, Create.RANDOM.nextDouble(0.28)-0.14D);
level.addParticle(ParticleTypes.FLAME, pos.getX() +random.nextFloat(1), pos.getY() + 1, pos.getZ() +random.nextFloat(1), Create.RANDOM.nextDouble(0.28)-0.14D, 0.14D, Create.RANDOM.nextDouble(0.28)-0.14D);
}
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
tankInventory.readFromNBT(compound.getCompound("TankContent"));
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
compound.put("TankContent", tankInventory.writeToNBT(new CompoundTag()));
}
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
@@ -154,11 +61,80 @@ public class FlarestackBlockEntity extends SmartBlockEntity implements IHaveGogg
return super.getCapability(cap, side);
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
public void invalidate() {
super.invalidate();
fluidCapability.invalidate();
}
}
protected void onFluidStackChanged(FluidStack newFluidStack) {
if (!hasLevel()) return;
sendData();
setChanged();
}
@Override
@SuppressWarnings("removal")
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
return TFMGUtils.createFluidTooltip(this, tooltip);
}
@Override
public void tick() {
super.tick();
if (tankInventory.isEmpty() || !tankInventory.isFluidValid(tankInventory.getFluid())) {
level.setBlock(getBlockPos(), this.getBlockState()
.setValue(FlarestackBlock.LIT, false), 2);
return;
}
float fillRatio = (float) tankInventory.getFluidAmount() / tankInventory.getCapacity();
// Dynamic drain rate: 30mB/t (empty) → 100mB/t (full)
int drainRate = 30 + (int) (70 * fillRatio);
if (tankInventory.getFluidAmount() > 0) {
tankInventory.drain(drainRate, IFluidHandler.FluidAction.EXECUTE);
smokeTimer = 100;
}
if (smokeTimer > 0) {
smokeTimer--;
// Light flarestack
level.setBlock(getBlockPos(), this.getBlockState()
.setValue(FlarestackBlock.LIT, true), 2);
// Spawn particles every 1-10 ticks
if ((level.getGameTime() + getBlockPos().hashCode()) % Math.max(1, 10 - (int) (9 * fillRatio)) == 0) {
makeParticles(level, getBlockPos());
}
}
}
public static void makeParticles(Level level, BlockPos pos) {
Random random = Create.RANDOM;
level.addParticle(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, pos.getX() +random.nextFloat(1), pos.getY() + 1, pos.getZ() +random.nextFloat(1), 0.0D, 0.08D, 0.0D);
level.addParticle(ParticleTypes.FLAME, pos.getX() +random.nextFloat(1), pos.getY() + 1, pos.getZ() +random.nextFloat(1), Create.RANDOM.nextDouble(0.28)-0.14D, 0.14D, Create.RANDOM.nextDouble(0.28)-0.14D);
level.addParticle(ParticleTypes.FLAME, pos.getX() +random.nextFloat(1), pos.getY() + 1, pos.getZ() +random.nextFloat(1), Create.RANDOM.nextDouble(0.28)-0.14D, 0.14D, Create.RANDOM.nextDouble(0.28)-0.14D);
level.addParticle(ParticleTypes.FLAME, pos.getX() +random.nextFloat(1), pos.getY() + 1, pos.getZ() +random.nextFloat(1), Create.RANDOM.nextDouble(0.28)-0.14D, 0.14D, Create.RANDOM.nextDouble(0.28)-0.14D);
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
tankInventory.readFromNBT(compound.getCompound("TankContent"));
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
compound.put("TankContent", tankInventory.writeToNBT(new CompoundTag()));
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {}
}

View File

@@ -28,25 +28,25 @@ import static com.drmangotea.tfmg.content.machinery.misc.smokestack.SmokestackBl
public class SmokestackBlockEntity extends SmartBlockEntity {
protected LazyOptional<IFluidHandler> fluidCapability;
public FluidTank tankInventory;
int smokeTimer = 0;
public FluidTank tankInventory;
protected LazyOptional<IFluidHandler> fluidCapability;
public SmokestackBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
tankInventory = createInventory();
fluidCapability = LazyOptional.of(() -> tankInventory);
}
tankInventory = new SmartFluidTank(8000, this::onFluidStackChanged) {
protected SmartFluidTank createInventory() {
return new SmartFluidTank(1000, this::onFluidStackChanged) {
@Override
public boolean isFluidValid(FluidStack stack) {
return stack.getFluid().isSame(TFMGFluids.CARBON_DIOXIDE.getSource());
}
};
fluidCapability = LazyOptional.of(() -> tankInventory);
}
@Nonnull
@@ -62,89 +62,68 @@ public class SmokestackBlockEntity extends SmartBlockEntity {
@Override
public void invalidate() {
super.invalidate();
fluidCapability.invalidate();
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
tankInventory.readFromNBT(compound.getCompound("TankContent"));
}
protected void onFluidStackChanged(FluidStack newFluidStack) {
if (!hasLevel())
return;
setChanged();
sendData();
}
public static void makeParticles(Level level, BlockPos pos) {
Random random = Create.RANDOM;
int shouldSpawnSmoke = random.nextInt(7);
if (shouldSpawnSmoke == 0) {
level.addParticle(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, pos.getX() + random.nextFloat(1), pos.getY() + 1, pos.getZ() + random.nextFloat(1), 0.0D, 0.08D, 0.0D);
}
}
@Override
public void tick() {
super.tick();
if (smokeTimer > 0) {
if (tankInventory.isEmpty()) return;
makeParticles(level, getBlockPos());
smokeTimer--;
}
if (tankInventory.isEmpty())
return;
float fillRatio = (float) tankInventory.getFluidAmount() / tankInventory.getCapacity();
// Dynamic drain rate: 10mB/t (empty) → 100mB/t (full)
int drainRate = 10 + (int) (90 * fillRatio);
if (getBlockState().getValue(TOP)) {
tankInventory.drain(tankInventory.getSpace() < 1000 ? 50 : 10, IFluidHandler.FluidAction.EXECUTE);
tankInventory.drain(drainRate, IFluidHandler.FluidAction.EXECUTE);
smokeTimer = 40;
}
if (smokeTimer > 0) {
smokeTimer--;
// Spawn particles every 1-10 ticks
if ((level.getGameTime() + getBlockPos().hashCode()) % Math.max(1, 10 - (int) (9 * fillRatio)) == 0) {
makeParticles(level, getBlockPos());
}
}
//Transfer smoke upwards
if (level.getBlockEntity(getBlockPos().above()) instanceof SmokestackBlockEntity be) {
int transferAmount = Math.min(tankInventory.getFluidAmount(), be.tankInventory.getCapacity() - be.tankInventory.getFluidAmount());
tankInventory.drain(transferAmount, IFluidHandler.FluidAction.EXECUTE);
be.tankInventory.fill(new FluidStack(TFMGFluids.CARBON_DIOXIDE.getSource(), transferAmount), IFluidHandler.FluidAction.EXECUTE);
}
}
public static void makeParticles(Level level, BlockPos pos) {
Random random = Create.RANDOM;
level.addParticle(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, pos.getX() + random.nextFloat(1), pos.getY() + 1, pos.getZ() + random.nextFloat(1), 0.0D, 0.08D, 0.0D);
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
tankInventory.readFromNBT(compound.getCompound("TankContent"));
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
compound.put("TankContent", tankInventory.writeToNBT(new CompoundTag()));
compound.putBoolean("Active", smokeTimer > 0);
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
}
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {}
}