#RI-37 fixed - Glitchy tank rendering

This commit is contained in:
Calclavia 2014-06-20 16:25:30 -07:00
parent 21dcffc100
commit 8bed6932ea
4 changed files with 312 additions and 306 deletions

View file

@ -25,14 +25,13 @@ public class TankNetwork extends FluidDistributionetwork
final FluidStack networkTankFluid = getTank().getFluid(); final FluidStack networkTankFluid = getTank().getFluid();
int lowestY = 255; int lowestY = 255;
int highestY = 0; int highestY = 0;
int connectorCount = 0; int connectorCount;
int totalFluid = networkTankFluid != null ? networkTankFluid.amount : 0; int totalFluid = networkTankFluid != null ? networkTankFluid.amount : 0;
//If we only have one tank only fill one tank //If we only have one tank only fill one tank
if (getConnectors().size() > 0) if (getConnectors().size() > 0)
{ {
IFluidDistribution tank = ((IFluidDistribution) getConnectors().toArray()[0]); IFluidDistribution tank = ((IFluidDistribution) getConnectors().toArray()[0]);
if (getConnectors().size() == 1) if (getConnectors().size() == 1)
{ {
@ -61,14 +60,14 @@ public class TankNetwork extends FluidDistributionetwork
} }
else else
{ {
HashMap<Integer, LinkedList<IFluidDistribution>> heightMap = new HashMap<Integer, LinkedList<IFluidDistribution>>(); HashMap<Integer, LinkedList<IFluidDistribution>> heightMap = new HashMap();
//Build map of all tanks by their y level //Build map of all tanks by their y level
for (IFluidDistribution connector : this.getConnectors()) for (IFluidDistribution connector : this.getConnectors())
{ {
if (connector instanceof TileEntity) if (connector instanceof TileEntity)
{ {
LinkedList<IFluidDistribution> list = new LinkedList<IFluidDistribution>(); LinkedList<IFluidDistribution> list = new LinkedList();
int yCoord = ((TileEntity) connector).yCoord; int yCoord = ((TileEntity) connector).yCoord;
if (yCoord < lowestY) if (yCoord < lowestY)

View file

@ -24,7 +24,6 @@ import resonant.lib.render.FluidRenderUtility;
import resonant.lib.render.RenderUtility; import resonant.lib.render.RenderUtility;
import resonant.lib.utility.FluidUtility; import resonant.lib.utility.FluidUtility;
import resonant.lib.utility.WorldUtility; import resonant.lib.utility.WorldUtility;
import resonant.lib.utility.inventory.InventoryUtility;
import resonant.lib.utility.render.RenderBlockUtility; import resonant.lib.utility.render.RenderBlockUtility;
import resonantinduction.archaic.Archaic; import resonantinduction.archaic.Archaic;
import resonantinduction.core.Reference; import resonantinduction.core.Reference;
@ -36,217 +35,219 @@ import universalelectricity.api.vector.Vector3;
import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly; import cpw.mods.fml.relauncher.SideOnly;
/** Tile/Block class for basic Dynamic tanks /**
* * Tile/Block class for basic Dynamic tanks
* @author Darkguardsman */ *
* @author Darkguardsman
*/
public class TileTank extends TileFluidDistribution implements IComparatorInputOverride, ISneakPickup public class TileTank extends TileFluidDistribution implements IComparatorInputOverride, ISneakPickup
{ {
public static final int VOLUME = 16; public static final int VOLUME = 16;
public TileTank() public TileTank()
{ {
super(UniversalElectricity.machine, VOLUME * FluidContainerRegistry.BUCKET_VOLUME); super(UniversalElectricity.machine, VOLUME * FluidContainerRegistry.BUCKET_VOLUME);
isOpaqueCube = false; isOpaqueCube = false;
normalRender = false; normalRender = false;
itemBlock = ItemBlockTank.class; itemBlock = ItemBlockTank.class;
} }
@Override @Override
public boolean shouldSideBeRendered(IBlockAccess access, int x, int y, int z, int side) public boolean shouldSideBeRendered(IBlockAccess access, int x, int y, int z, int side)
{ {
return access != null && block != null && access.getBlockId(x, y, z) != block.blockID; return access != null && block != null && access.getBlockId(x, y, z) != block.blockID;
} }
@Override @Override
protected boolean use(EntityPlayer player, int side, Vector3 vector3) protected boolean use(EntityPlayer player, int side, Vector3 vector3)
{ {
if (!world().isRemote) if (!world().isRemote)
{ {
return FluidUtility.playerActivatedFluidItem(world(), x(), y(), z(), player, side); return FluidUtility.playerActivatedFluidItem(world(), x(), y(), z(), player, side);
} }
return true; return true;
} }
@Override @Override
public int getComparatorInputOverride(int side) public int getComparatorInputOverride(int side)
{ {
if (getNetwork().getTank().getFluid() != null) if (getNetwork().getTank().getFluid() != null)
{ {
return (int) (15 * ((double) getNetwork().getTank().getFluidAmount() / (double) getNetwork().getTank().getCapacity())); return (int) (15 * ((double) getNetwork().getTank().getFluidAmount() / (double) getNetwork().getTank().getCapacity()));
} }
return 0; return 0;
} }
@Override @Override
public int getLightValue(IBlockAccess access) public int getLightValue(IBlockAccess access)
{ {
if (getInternalTank().getFluid() != null) if (getInternalTank().getFluid() != null)
{ {
return getInternalTank().getFluid().getFluid().getLuminosity(); return getInternalTank().getFluid().getFluid().getLuminosity();
} }
return super.getLightValue(access); return super.getLightValue(access);
} }
@Override @Override
public FluidDistributionetwork getNetwork() public FluidDistributionetwork getNetwork()
{ {
if (this.network == null) if (this.network == null)
{ {
this.network = new TankNetwork(); this.network = new TankNetwork();
this.network.addConnector(this); this.network.addConnector(this);
} }
return this.network; return this.network;
} }
@Override @Override
public void setNetwork(FluidDistributionetwork network) public void setNetwork(FluidDistributionetwork network)
{ {
if (network instanceof TankNetwork) if (network instanceof TankNetwork)
{ {
this.network = network; this.network = network;
} }
} }
@Override @Override
public void validateConnectionSide(TileEntity tileEntity, ForgeDirection side) public void validateConnectionSide(TileEntity tileEntity, ForgeDirection side)
{ {
if (!this.worldObj.isRemote) if (!this.worldObj.isRemote)
{ {
if (tileEntity instanceof TileTank) if (tileEntity instanceof TileTank)
{ {
getNetwork().merge(((IFluidDistribution) tileEntity).getNetwork()); getNetwork().merge(((IFluidDistribution) tileEntity).getNetwork());
renderSides = WorldUtility.setEnableSide(renderSides, side, true); renderSides = WorldUtility.setEnableSide(renderSides, side, true);
connectedBlocks[side.ordinal()] = tileEntity; connectedBlocks[side.ordinal()] = tileEntity;
} }
} }
} }
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
@Override @Override
protected TileRender newRenderer() protected TileRender newRenderer()
{ {
return new TileRender() return new TileRender()
{ {
@Override @Override
public boolean renderStatic(RenderBlocks renderer, Vector3 position) public boolean renderStatic(RenderBlocks renderer, Vector3 position)
{ {
RenderBlockUtility.tessellateBlockWithConnectedTextures(renderSides, world(), x(), y(), z(), Archaic.blockTank, null, RenderUtility.getIcon(Reference.PREFIX + "tankEdge")); RenderBlockUtility.tessellateBlockWithConnectedTextures(renderSides, world(), x(), y(), z(), Archaic.blockTank, null, RenderUtility.getIcon(Reference.PREFIX + "tankEdge"));
return true; return true;
} }
public void renderTank(TileEntity tileEntity, double x, double y, double z, FluidStack fluid) public void renderTank(TileEntity tileEntity, double x, double y, double z, FluidStack fluid)
{ {
if (tileEntity.worldObj != null && tileEntity instanceof TileTank) if (tileEntity.worldObj != null && tileEntity instanceof TileTank)
{ {
GL11.glPushMatrix(); GL11.glPushMatrix();
GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5); GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5);
if (fluid != null) if (fluid != null)
{ {
GL11.glPushMatrix(); GL11.glPushMatrix();
if (!fluid.getFluid().isGaseous()) if (!fluid.getFluid().isGaseous())
{ {
GL11.glScaled(0.99, 0.99, 0.99); GL11.glScaled(0.99, 0.99, 0.99);
FluidTank tank = ((TileTank) tileEntity).getInternalTank(); FluidTank tank = ((TileTank) tileEntity).getInternalTank();
double percentageFilled = (double) tank.getFluidAmount() / (double) tank.getCapacity(); double percentageFilled = (double) tank.getFluidAmount() / (double) tank.getCapacity();
double ySouthEast = FluidUtility.getAveragePercentageFilledForSides(TileTank.class, percentageFilled, tileEntity.worldObj, new Vector3(tileEntity), ForgeDirection.SOUTH, ForgeDirection.EAST); double ySouthEast = FluidUtility.getAveragePercentageFilledForSides(TileTank.class, percentageFilled, tileEntity.worldObj, new Vector3(tileEntity), ForgeDirection.SOUTH, ForgeDirection.EAST);
double yNorthEast = FluidUtility.getAveragePercentageFilledForSides(TileTank.class, percentageFilled, tileEntity.worldObj, new Vector3(tileEntity), ForgeDirection.NORTH, ForgeDirection.EAST); double yNorthEast = percentageFilled;//FluidUtility.getAveragePercentageFilledForSides(TileTank.class, percentageFilled, tileEntity.worldObj, new Vector3(tileEntity), ForgeDirection.NORTH, ForgeDirection.EAST);
double ySouthWest = FluidUtility.getAveragePercentageFilledForSides(TileTank.class, percentageFilled, tileEntity.worldObj, new Vector3(tileEntity), ForgeDirection.SOUTH, ForgeDirection.WEST); double ySouthWest = percentageFilled;//FluidUtility.getAveragePercentageFilledForSides(TileTank.class, percentageFilled, tileEntity.worldObj, new Vector3(tileEntity), ForgeDirection.SOUTH, ForgeDirection.WEST);
double yNorthWest = FluidUtility.getAveragePercentageFilledForSides(TileTank.class, percentageFilled, tileEntity.worldObj, new Vector3(tileEntity), ForgeDirection.NORTH, ForgeDirection.WEST); double yNorthWest = percentageFilled;//FluidUtility.getAveragePercentageFilledForSides(TileTank.class, percentageFilled, tileEntity.worldObj, new Vector3(tileEntity), ForgeDirection.NORTH, ForgeDirection.WEST);
FluidRenderUtility.renderFluidTesselation(tank, ySouthEast, yNorthEast, ySouthWest, yNorthWest); FluidRenderUtility.renderFluidTesselation(tank, ySouthEast, yNorthEast, ySouthWest, yNorthWest);
} }
else else
{ {
GL11.glTranslated(-0.5, -0.5, -0.5); GL11.glTranslated(-0.5, -0.5, -0.5);
GL11.glScaled(0.99, 0.99, 0.99); GL11.glScaled(0.99, 0.99, 0.99);
int capacity = tileEntity instanceof TileTank ? ((TileTank) tileEntity).getInternalTank().getCapacity() : fluid.amount; int capacity = tileEntity instanceof TileTank ? ((TileTank) tileEntity).getInternalTank().getCapacity() : fluid.amount;
double filledPercentage = (double) fluid.amount / (double) capacity; double filledPercentage = (double) fluid.amount / (double) capacity;
double renderPercentage = fluid.getFluid().isGaseous() ? 1 : filledPercentage; double renderPercentage = fluid.getFluid().isGaseous() ? 1 : filledPercentage;
int[] displayList = FluidRenderUtility.getFluidDisplayLists(fluid, tileEntity.worldObj, false); int[] displayList = FluidRenderUtility.getFluidDisplayLists(fluid, tileEntity.worldObj, false);
GL11.glPushAttrib(GL11.GL_ENABLE_BIT); GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
GL11.glEnable(GL11.GL_CULL_FACE); GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glDisable(GL11.GL_LIGHTING); GL11.glDisable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_BLEND); GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
Color color = new Color(fluid.getFluid().getColor()); Color color = new Color(fluid.getFluid().getColor());
RenderUtility.enableBlending(); RenderUtility.enableBlending();
GL11.glColor4d(color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f, fluid.getFluid().isGaseous() ? filledPercentage : 1); GL11.glColor4d(color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f, fluid.getFluid().isGaseous() ? filledPercentage : 1);
RenderUtility.bind(FluidRenderUtility.getFluidSheet(fluid)); RenderUtility.bind(FluidRenderUtility.getFluidSheet(fluid));
GL11.glCallList(displayList[(int) (renderPercentage * (FluidRenderUtility.DISPLAY_STAGES - 1))]); GL11.glCallList(displayList[(int) (renderPercentage * (FluidRenderUtility.DISPLAY_STAGES - 1))]);
RenderUtility.disableBlending(); RenderUtility.disableBlending();
GL11.glPopAttrib(); GL11.glPopAttrib();
} }
GL11.glPopMatrix(); GL11.glPopMatrix();
} }
GL11.glPopMatrix(); GL11.glPopMatrix();
} }
} }
@Override @Override
public boolean renderDynamic(Vector3 position, boolean isItem, float frame) public boolean renderDynamic(Vector3 position, boolean isItem, float frame)
{ {
renderTank(TileTank.this, position.x, position.y, position.z, getInternalTank().getFluid()); renderTank(TileTank.this, position.x, position.y, position.z, getInternalTank().getFluid());
return false; return false;
} }
@Override @Override
public boolean renderItem(ItemStack itemStack) public boolean renderItem(ItemStack itemStack)
{ {
GL11.glPushMatrix(); GL11.glPushMatrix();
GL11.glTranslated(0.5, 0.5, 0.5); GL11.glTranslated(0.5, 0.5, 0.5);
RenderBlockUtility.tessellateBlockWithConnectedTextures(itemStack.getItemDamage(), Archaic.blockTank, null, RenderUtility.getIcon(Reference.PREFIX + "tankEdge")); RenderBlockUtility.tessellateBlockWithConnectedTextures(itemStack.getItemDamage(), Archaic.blockTank, null, RenderUtility.getIcon(Reference.PREFIX + "tankEdge"));
GL11.glPopMatrix(); GL11.glPopMatrix();
GL11.glPushMatrix(); GL11.glPushMatrix();
GL11.glTranslated(0, -0.1, 0); GL11.glTranslated(0, -0.1, 0);
FluidStack fluid = null; FluidStack fluid = null;
if (itemStack.getTagCompound() != null && itemStack.getTagCompound().hasKey("fluid")) if (itemStack.getTagCompound() != null && itemStack.getTagCompound().hasKey("fluid"))
{ {
fluid = FluidStack.loadFluidStackFromNBT(itemStack.getTagCompound().getCompoundTag("fluid")); fluid = FluidStack.loadFluidStackFromNBT(itemStack.getTagCompound().getCompoundTag("fluid"));
} }
renderTank(TileTank.this, 0, 0, 0, fluid); renderTank(TileTank.this, 0, 0, 0, fluid);
GL11.glPopMatrix(); GL11.glPopMatrix();
return true; return true;
} }
}; };
} }
@Override @Override
public List<ItemStack> getRemovedItems(EntityPlayer entity) public List<ItemStack> getRemovedItems(EntityPlayer entity)
{ {
List<ItemStack> drops = new ArrayList<ItemStack>(); List<ItemStack> drops = new ArrayList();
ItemStack itemStack = new ItemStack(Archaic.blockTank, 1, 0); ItemStack itemStack = new ItemStack(Archaic.blockTank, 1, 0);
if (itemStack != null) if (itemStack != null)
{ {
if (getInternalTank() != null && getInternalTank().getFluid() != null) if (getInternalTank() != null && getInternalTank().getFluid() != null)
{ {
FluidStack stack = getInternalTank().getFluid(); FluidStack stack = getInternalTank().getFluid();
if (stack != null) if (stack != null)
{ {
if (itemStack.getTagCompound() == null) if (itemStack.getTagCompound() == null)
{ {
itemStack.setTagCompound(new NBTTagCompound()); itemStack.setTagCompound(new NBTTagCompound());
} }
drain(ForgeDirection.UNKNOWN, stack.amount, false); drain(ForgeDirection.UNKNOWN, stack.amount, false);
itemStack.getTagCompound().setCompoundTag("fluid", stack.writeToNBT(new NBTTagCompound())); itemStack.getTagCompound().setCompoundTag("fluid", stack.writeToNBT(new NBTTagCompound()));
} }
} }
drops.add(itemStack); drops.add(itemStack);
} }
return drops; return drops;
} }
} }

View file

@ -9,145 +9,151 @@ import net.minecraftforge.fluids.FluidTankInfo;
import resonant.lib.utility.WorldUtility; import resonant.lib.utility.WorldUtility;
import universalelectricity.api.vector.Vector3; import universalelectricity.api.vector.Vector3;
/** A prefab class for tiles that use the fluid network. /**
* * A prefab class for tiles that use the fluid network.
* @author DarkGuardsman */ *
* @author DarkGuardsman
*/
public abstract class TileFluidDistribution extends TileFluidNode implements IFluidDistribution public abstract class TileFluidDistribution extends TileFluidNode implements IFluidDistribution
{ {
protected Object[] connectedBlocks = new Object[6]; protected Object[] connectedBlocks = new Object[6];
/** Network used to link all parts together */ /**
protected FluidDistributionetwork network; * Network used to link all parts together
*/
protected FluidDistributionetwork network;
public TileFluidDistribution(Material material, int tankSize) public TileFluidDistribution(Material material, int tankSize)
{ {
super(material, tankSize); super(material, tankSize);
} }
@Override @Override
public void initiate() public void initiate()
{ {
super.initiate(); super.initiate();
refresh(); refresh();
getNetwork().reconstruct(); getNetwork().reconstruct();
} }
@Override @Override
protected void onNeighborChanged() protected void onNeighborChanged()
{ {
refresh(); refresh();
} }
@Override @Override
public void invalidate() public void invalidate()
{ {
this.getNetwork().split(this); this.getNetwork().split(this);
super.invalidate(); super.invalidate();
} }
@Override @Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill) public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
{ {
return getNetwork().fill(this, from, resource, doFill); return getNetwork().fill(this, from, resource, doFill);
} }
@Override @Override
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
{ {
return getNetwork().drain(this, from, resource, doDrain); return getNetwork().drain(this, from, resource, doDrain);
} }
@Override @Override
public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
{ {
return getNetwork().drain(this, from, maxDrain, doDrain); return getNetwork().drain(this, from, maxDrain, doDrain);
} }
@Override @Override
public boolean canFill(ForgeDirection from, Fluid fluid) public boolean canFill(ForgeDirection from, Fluid fluid)
{ {
return true; return true;
} }
@Override @Override
public boolean canDrain(ForgeDirection from, Fluid fluid) public boolean canDrain(ForgeDirection from, Fluid fluid)
{ {
return true; return true;
} }
@Override @Override
public FluidTankInfo[] getTankInfo(ForgeDirection from) public FluidTankInfo[] getTankInfo(ForgeDirection from)
{ {
return new FluidTankInfo[] { getNetwork().getTank().getInfo() }; return new FluidTankInfo[] { getInternalTank().getInfo() };
} }
@Override @Override
public Object[] getConnections() public Object[] getConnections()
{ {
return connectedBlocks; return connectedBlocks;
} }
public void refresh() public void refresh()
{ {
if (this.worldObj != null && !this.worldObj.isRemote) if (this.worldObj != null && !this.worldObj.isRemote)
{ {
byte previousConnections = renderSides; byte previousConnections = renderSides;
connectedBlocks = new Object[6]; connectedBlocks = new Object[6];
renderSides = 0; renderSides = 0;
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS)
{ {
this.validateConnectionSide(new Vector3(this).translate(dir).getTileEntity(worldObj), dir); this.validateConnectionSide(new Vector3(this).translate(dir).getTileEntity(worldObj), dir);
} }
/** Only send packet updates if visuallyConnected changed. */ /** Only send packet updates if visuallyConnected changed. */
if (previousConnections != renderSides) if (previousConnections != renderSides)
{ {
getNetwork().update(); getNetwork().update();
getNetwork().reconstruct(); getNetwork().reconstruct();
sendRenderUpdate(); sendRenderUpdate();
} }
} }
} }
/** Checks to make sure the connection is valid to the tileEntity /**
* * Checks to make sure the connection is valid to the tileEntity
* @param tileEntity - the tileEntity being checked *
* @param side - side the connection is too */ * @param tileEntity - the tileEntity being checked
public void validateConnectionSide(TileEntity tileEntity, ForgeDirection side) * @param side - side the connection is too
{ */
if (!this.worldObj.isRemote) public void validateConnectionSide(TileEntity tileEntity, ForgeDirection side)
{ {
if (tileEntity instanceof IFluidDistribution) if (!this.worldObj.isRemote)
{ {
this.getNetwork().merge(((IFluidDistribution) tileEntity).getNetwork()); if (tileEntity instanceof IFluidDistribution)
renderSides = WorldUtility.setEnableSide(renderSides, side, true); {
connectedBlocks[side.ordinal()] = tileEntity; this.getNetwork().merge(((IFluidDistribution) tileEntity).getNetwork());
} renderSides = WorldUtility.setEnableSide(renderSides, side, true);
} connectedBlocks[side.ordinal()] = tileEntity;
} }
}
}
public int getSubID() public int getSubID()
{ {
return this.colorID; return this.colorID;
} }
public void setSubID(int id) public void setSubID(int id)
{ {
this.colorID = id; this.colorID = id;
} }
@Override @Override
public boolean canConnect(ForgeDirection direction, Object obj) public boolean canConnect(ForgeDirection direction, Object obj)
{ {
return true; return true;
} }
@Override @Override
public IFluidDistribution getInstance(ForgeDirection from) public IFluidDistribution getInstance(ForgeDirection from)
{ {
return this; return this;
} }
} }

View file

@ -57,7 +57,7 @@ public abstract class TileFluidNode extends TileBase implements IPacketReceiverW
sendTankUpdate(); sendTankUpdate();
markTankUpdate = false; markTankUpdate = false;
} }
} }
@Override @Override
public void readFromNBT(NBTTagCompound nbt) public void readFromNBT(NBTTagCompound nbt)
@ -138,7 +138,7 @@ public abstract class TileFluidNode extends TileBase implements IPacketReceiverW
{ {
if (!worldObj.isRemote) if (!worldObj.isRemote)
{ {
if (!FluidUtility.matchExact(prevStack, getInternalTank().getFluid())) if (!FluidUtility.matchExact(prevStack, getInternalTank().getFluid()) || ticks == 0)
{ {
markTankUpdate = true; markTankUpdate = true;
prevStack = tank.getFluid() != null ? tank.getFluid().copy() : null; prevStack = tank.getFluid() != null ? tank.getFluid().copy() : null;