Fix Certus Quartz fluid flickering and sometimes rendering an incorrect amount of fluid, optimize packet sending and ticking (#348)

Co-authored-by: Martin Robertz <dream-master@gmx.net>
This commit is contained in:
danyadevandMartin Robertz authored and GitHub committed 2025-11-14 23:20:19 +01:00
1 parent 219f8c313a
commit 2e6bfe6aac
4 files changed
+62 -98

No files matched your search

@@ -2,7 +2,6 @@ package com.glodblock.github.common.block;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.entity.player.EntityPlayer;
@@ -20,7 +19,6 @@ import net.minecraftforge.fluids.FluidStack;
import com.glodblock.github.common.item.ItemCertusQuartzTank;
import com.glodblock.github.common.tabs.FluidCraftingTabs;
import com.glodblock.github.common.tile.TileCertusQuartzTank;
import com.glodblock.github.loader.ChannelLoader;
import com.glodblock.github.loader.IRegister;
import com.glodblock.github.loader.ItemAndBlockHolder;
import com.glodblock.github.util.NameConst;
@@ -167,13 +165,6 @@ public class BlockCertusQuartzTank extends BaseBlockContainer implements IRegist
return false;
}
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, Block neighborBlock) {
if (!world.isRemote) {
ChannelLoader.sendPacketToAllPlayers(world.getTileEntity(x, y, z).getDescriptionPacket(), world);
}
}
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
@SideOnly(Side.CLIENT)
@@ -138,19 +138,14 @@ public class ItemCertusQuartzTank extends BaseItemBlockContainer implements IFlu
@Override
public boolean placeBlockAt(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side,
float hitX, float hitY, float hitZ, int metadata) {
if (!world.setBlock(x, y, z, this.field_150939_a, metadata, 3)) {
if (!super.placeBlockAt(stack, player, world, x, y, z, side, hitX, hitY, hitZ, metadata)) {
return false;
}
if (world.getBlock(x, y, z) == this.field_150939_a) {
this.field_150939_a.onBlockPlacedBy(world, x, y, z, player, stack);
this.field_150939_a.onPostBlockPlaced(world, x, y, z, metadata);
if (stack != null) {
((TileCertusQuartzTank) world.getTileEntity(x, y, z)).readFromItemNBT(stack.getTagCompound());
}
if (stack != null && stack.hasTagCompound()) {
((TileCertusQuartzTank) world.getTileEntity(x, y, z))
.readFromNBTWithoutCoords(stack.getTagCompound().getCompoundTag("tileEntity"));
}
return true;
}
}
@@ -1,12 +1,10 @@
package com.glodblock.github.common.tile;
import net.minecraft.block.Block;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
@@ -14,14 +12,11 @@ import net.minecraftforge.fluids.FluidTank;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
import com.glodblock.github.loader.ChannelLoader;
import com.glodblock.github.util.BlockPos;
public class TileCertusQuartzTank extends TileEntity implements IFluidHandler {
private FluidStack lastBeforeUpdate = null;
public FluidTank tank = new FluidTank(32000);
private boolean hasUpdate;
@Override
public boolean canDrain(ForgeDirection from, Fluid fluid) {
@@ -38,32 +33,6 @@ public class TileCertusQuartzTank extends TileEntity implements IFluidHandler {
return tankFluid == null || tankFluid.amount == 0 ? 0 : tankFluid.getFluid().getLuminosity(tankFluid);
}
public void compareAndUpdate() {
if (this.worldObj.isRemote) {
return;
}
FluidStack current = this.tank.getFluid();
if (current == null || this.lastBeforeUpdate == null) {
if (current != this.lastBeforeUpdate) {
ChannelLoader.sendPacketToAllPlayers(getDescriptionPacket(), this.worldObj);
this.lastBeforeUpdate = current == null ? null : current.copy();
}
return;
}
boolean amountSufficientlyChanged = Math.abs(current.amount - this.lastBeforeUpdate.amount) >= 500;
boolean isFull = current.amount == this.tank.getCapacity();
boolean wasFull = this.lastBeforeUpdate.amount == this.tank.getCapacity();
boolean fullStateChanged = isFull != wasFull;
if (amountSufficientlyChanged || fullStateChanged) {
ChannelLoader.sendPacketToAllPlayers(getDescriptionPacket(), this.worldObj);
this.lastBeforeUpdate = current.copy();
}
}
public FluidStack drain(FluidStack fluid, boolean doDrain, boolean findMainTank) {
if (fluid == null || this.getFluid() == null || this.getFluid() != fluid.getFluid()) {
return null;
@@ -88,7 +57,9 @@ public class TileCertusQuartzTank extends TileEntity implements IFluidHandler {
FluidStack drainedFluid = this.tank.drain(fluid.amount, doDrain);
int drained = drainedFluid != null ? drainedFluid.amount : 0;
compareAndUpdate();
if (drained > 0) {
update();
}
if (drained < fluid.amount) {
TileCertusQuartzTank tankBelow = this.getTankBelow();
@@ -144,7 +115,10 @@ public class TileCertusQuartzTank extends TileEntity implements IFluidHandler {
}
int filled = this.tank.fill(fluid, doFill);
compareAndUpdate();
if (filled > 0) {
update();
}
if (filled < fluid.amount) {
TileCertusQuartzTank tankAbove = this.getTankAbove();
@@ -165,13 +139,6 @@ public class TileCertusQuartzTank extends TileEntity implements IFluidHandler {
return fill(resource, doFill, true);
}
@Override
public Packet getDescriptionPacket() {
NBTTagCompound nbtTag = new NBTTagCompound();
writeToNBT(nbtTag);
return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 1, nbtTag);
}
public Fluid getFluid() {
FluidStack tankFluid = this.tank.getFluid();
return tankFluid != null && tankFluid.amount > 0 ? tankFluid.getFluid() : null;
@@ -185,31 +152,6 @@ public class TileCertusQuartzTank extends TileEntity implements IFluidHandler {
return (float) this.tank.getFluidAmount() / this.tank.getCapacity();
}
private void onComparatorUpdate(World world, int x, int y, int z, Block block) {
world.func_147453_f(x, y, z, block);
}
@Override
public void updateEntity() {
if (this.tank.getFluid() != null) {
TileCertusQuartzTank below = getTankBelow();
if (below != null) {
FluidStack filled = this.tank.getFluid().copy();
filled.amount = below.fill(this.tank.getFluid(), true, true);
if (filled.amount >= 0) {
this.drain(filled, true, true);
this.hasUpdate = true;
below.hasUpdate = true;
}
}
}
if (this.hasUpdate) {
onComparatorUpdate(this.worldObj, this.xCoord, this.yCoord, this.zCoord, this.getBlockType());
this.hasUpdate = false;
}
}
private TileCertusQuartzTank getTankAbove() {
TileEntity tile = new BlockPos(this).getOffSet(0, 1, 0).getTileEntity();
if (tile instanceof TileCertusQuartzTank tankTile) {
@@ -268,6 +210,49 @@ public class TileCertusQuartzTank extends TileEntity implements IFluidHandler {
return getTankInfo(true);
}
public FluidTankInfo[] getInternalFluid() {
return this.getTankInfo(true);
}
private void flowFluidDown(boolean checkTankAbove) {
if (this.getFluid() != null) {
TileCertusQuartzTank below = getTankBelow();
if (below != null) {
FluidStack fluid = this.tank.getFluid().copy();
int amount = below.tank.fill(fluid, true);
if (amount > 0) {
this.tank.drain(amount, true);
this.update();
below.update();
below.flowFluidDown(false);
}
}
}
if (checkTankAbove) {
TileCertusQuartzTank above = getTankAbove();
if (above != null && above.getFluid() != null) {
if (this.getFluid() == null || this.getFluid() == above.getFluid()) {
above.flowFluidDown(true);
}
}
}
}
public void update() {
if (!this.worldObj.isRemote) {
markDirty();
this.worldObj.markBlockForUpdate(this.xCoord, this.yCoord, this.zCoord);
}
}
@Override
public Packet getDescriptionPacket() {
NBTTagCompound nbtTag = new NBTTagCompound();
writeToNBT(nbtTag);
return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 1, nbtTag);
}
@Override
public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity packet) {
this.worldObj.markBlockRangeForRenderUpdate(
@@ -290,6 +275,15 @@ public class TileCertusQuartzTank extends TileEntity implements IFluidHandler {
this.tank.readFromNBT(tag);
}
// Specifically used when player is placing a tank in world,
// so we can apply the item's NBT and flow down its fluid in lower tanks
public void readFromItemNBT(NBTTagCompound tag) {
if (tag != null) {
this.readFromNBTWithoutCoords(tag.getCompoundTag("tileEntity"));
}
this.flowFluidDown(true);
}
@Override
public void writeToNBT(NBTTagCompound tag) {
super.writeToNBT(tag);
@@ -299,8 +293,4 @@ public class TileCertusQuartzTank extends TileEntity implements IFluidHandler {
public void writeToNBTWithoutCoords(NBTTagCompound tag) {
this.tank.writeToNBT(tag);
}
public FluidTankInfo[] getInternalFluid() {
return this.getTankInfo(true);
}
}
@@ -1,9 +1,5 @@
package com.glodblock.github.loader;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.Packet;
import net.minecraft.world.World;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.network.CPacketCraftRequest;
import com.glodblock.github.network.CPacketDumpTank;
@@ -100,12 +96,4 @@ public class ChannelLoader implements Runnable {
id++,
Side.CLIENT);
}
public static void sendPacketToAllPlayers(Packet packet, World world) {
for (Object player : world.playerEntities) {
if (player instanceof EntityPlayerMP) {
((EntityPlayerMP) player).playerNetServerHandler.sendPacket(packet);
}
}
}
}