Jump to content

Recommended Posts

Posted

Good day!

 

For quite some time now I've tried to create a simple block that is able to hold liquids, just like a BuildCraft tank for example. It kind of works, but on interaction with transfer nodes or pipes client desyncs from the server (client value always stays a bit higher than the server value). So I was wondering if somebody could help me and show me what is a proper way to make a liquid tank.

 

Here's my current code if anybody wants to see that:

package com.krizo.brewmaster.tileEntity;

import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTank;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
import net.minecraftforge.fluids.IFluidTank;

public class TileEntitySTank extends TileEntity implements IFluidHandler{

public FluidTank tank = new FluidTank(10000);
private boolean needsUpdate = false;
private int updateTimer = 0;

public TileEntitySTank()
{
}

public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
  {
	needsUpdate = true;
    return this.tank.fill(resource, doFill);
  }
  
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
{
        return this.tank.drain(resource.amount, doDrain);
}

public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
{
	needsUpdate = true;
        return this.tank.drain(maxDrain, doDrain);
}
  
public boolean canFill(ForgeDirection from, Fluid fluid)
{
	return true;
}
  
public boolean canDrain(ForgeDirection from, Fluid fluid)
{
	return true;
}

public FluidTankInfo[] getTankInfo(ForgeDirection from)
  {
    return new FluidTankInfo[] {this.tank.getInfo()};
  }

public float getAdjustedVolume()
{
	float amount = tank.getFluidAmount();
	float capacity = tank.getCapacity();
	float volume = (amount/capacity)*0.8F;		
	return volume;
}

public void updateEntity() 
{
	if (needsUpdate) 
	{
		if (updateTimer == 0) 
		{ 
			updateTimer = 10; // every 10 ticks it will send an update
		} 
		else 
		{ 
			--updateTimer;
			if (updateTimer == 0) 
			{ 
				worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
				needsUpdate = false;
			}
		}
	}
}

@Override
    public void readFromNBT(NBTTagCompound tag)
    {
        super.readFromNBT(tag);
        tank.readFromNBT(tag);
    }

    @Override
    public void writeToNBT(NBTTagCompound tag)
    {
        super.writeToNBT(tag);
        tank.writeToNBT(tag);
    }
    
@Override
public Packet getDescriptionPacket()
{
	NBTTagCompound tag = new NBTTagCompound();
	writeToNBT(tag);
	return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, this.blockMetadata, tag);
}

@Override
public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt)
{
	NBTTagCompound tag = pkt.func_148857_g();
	readFromNBT(tag);
}
}

 

Thanks!

Posted

Everything seems fine, except when I pump liquid out with any kind of pipe (Buildcraft, Extra Utilities) the client value always lags behind the server value and when the server value gets to 0, the client value is stuck at let's say 20 or 30 or someother value until I reload the world. I don't know why they are not in sync. I've been having trouble with this for a month now.

Posted

Try locking "needsUpdate" to true so it constantly updates every 10 ticks. If that fixes it then it is a problem with the way you check if an update is required.

 

Edit: Take a look at how the tinkerers construct tank works.

https://github.com/SlimeKnights/TinkersConstruct/blob/master/src/main/java/tconstruct/smeltery/logic/LavaTankLogic.java

it looks like it just updates the block whenever the storage is changed.

I am the author of Draconic Evolution

Posted

Try locking "needsUpdate" to true so it constantly updates every 10 ticks. If that fixes it then it is a problem with the way you check if an update is required.

 

Edit: Take a look at how the tinkerers construct tank works.

https://github.com/SlimeKnights/TinkersConstruct/blob/master/src/main/java/tconstruct/smeltery/logic/LavaTankLogic.java

it looks like it just updates the block whenever the storage is changed.

 

It wasn't that, because I had it update constantly before, BUT showing me this code helped me realize that the problem was in how I was writing and reading data from/to NBT so editing that fixed my problem. Thanks! :D

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.