electrodynamics/src/main/scala/edx/basic/fluid/tank/TileTank.scala

215 lines
7.6 KiB
Scala

package edx.basic.fluid.tank
import java.awt.Color
import java.util.{ArrayList, List}
import cpw.mods.fml.relauncher.{Side, SideOnly}
import edx.basic.BasicContent
import edx.basic.fluid.gutter.NodeFluidGravity
import edx.core.Reference
import edx.core.prefab.node.TileFluidProvider
import net.minecraft.block.material.Material
import net.minecraft.client.renderer.RenderBlocks
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.world.IBlockAccess
import net.minecraftforge.common.util.ForgeDirection
import net.minecraftforge.fluids._
import org.lwjgl.opengl.GL11
import resonantengine.api.graph.node.INode
import resonantengine.api.tile.IRemovable.ISneakPickup
import resonantengine.lib.grid.core.Node
import resonantengine.lib.render.block.RenderConnectedTexture
import resonantengine.lib.render.{FluidRenderUtility, RenderBlockUtility, RenderUtility}
import resonantengine.lib.transform.vector.Vector3
import resonantengine.lib.utility.FluidUtility
import resonantengine.lib.wrapper.BitmaskWrapper._
/**
* Tile/Block class for basic Dynamic tanks
*
* @author Darkguardsman
*/
class TileTank extends TileFluidProvider(Material.iron) with ISneakPickup with RenderConnectedTexture
{
edgeTexture = Reference.prefix + "tankEdge"
isOpaqueCube = false
normalRender = false
itemBlock = classOf[ItemBlockTank]
fluidNode = new NodeFluidGravity(this, 16 * FluidContainerRegistry.BUCKET_VOLUME)
{
override def connect[B <: IFluidHandler](obj: B, dir: ForgeDirection)
{
super.connect(obj, dir)
if (obj.isInstanceOf[INode] && !obj.asInstanceOf[Node].parent.isInstanceOf[TileTank])
_connectedMask = _connectedMask.closeMask(dir)
}
override def fill(from: ForgeDirection, resource: FluidStack, doFill: Boolean): Int =
{
//Try to fill the current tank. If it fails, try to fill the tank above it.
val result = super.fill(from, resource, doFill)
if (result == 0)
{
val tile = (toVectorWorld + new Vector3(0, 1, 0)).getTileEntity
if (tile.isInstanceOf[TileTank])
{
return tile.asInstanceOf[TileTank].fill(from, resource, doFill)
}
}
return result
}
}
fluidNode.asInstanceOf[NodeFluidGravity].maxFlowRate = FluidContainerRegistry.BUCKET_VOLUME
fluidNode.asInstanceOf[NodeFluidGravity].doPressureUpdate = false
fluidNode.onFluidChanged = () => if (!world.isRemote && !isInvalid) sendPacket(1)
override def shouldSideBeRendered(access: IBlockAccess, x: Int, y: Int, z: Int, side: Int): Boolean = new Vector3(x, y, z).getBlock(access) != block
override def use(player: EntityPlayer, side: Int, vector3: Vector3): Boolean =
{
if (!world.isRemote)
{
return FluidUtility.playerActivatedFluidItem(world, x.toInt, y.toInt, z.toInt, player, side)
}
return true
}
override def getLightValue(access: IBlockAccess): Int =
{
if (fluidNode.getTank.getFluid != null && fluidNode.getTank.getFluid.getFluid != null)
{
return fluidNode.getTank.getFluid.getFluid.getLuminosity
}
return super.getLightValue(access)
}
@SideOnly(Side.CLIENT)
override def renderStatic(renderer: RenderBlocks, pos: Vector3, pass: Int): Boolean =
{
RenderBlockUtility.tessellateBlockWithConnectedTextures(clientRenderMask, world, pos.xi, pos.yi, pos.zi, tile.getBlockType, if (faceTexture != null) RenderUtility.getIcon(faceTexture) else null, RenderUtility.getIcon(edgeTexture))
return true
}
@SideOnly(Side.CLIENT)
override def renderDynamic(position: Vector3, frame: Float, pass: Int)
{
renderTankFluid(position.x, position.y, position.z, fluidNode.getTank.getFluid)
}
/**
* Renders the fluid inside the tank
*/
@SideOnly(Side.CLIENT)
def renderTankFluid(x: Double, y: Double, z: Double, fluid: FluidStack)
{
if (world != null)
{
GL11.glPushMatrix()
GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5)
if (fluid != null)
{
GL11.glPushMatrix()
if (!fluid.getFluid.isGaseous)
{
GL11.glScaled(0.99, 0.99, 0.99)
val tank: IFluidTank = fluidNode.getTank
val percentageFilled: Double = tank.getFluidAmount.toDouble / tank.getCapacity.toDouble
val ySouthEast = FluidUtility.getAveragePercentageFilledForSides(classOf[TileTank], percentageFilled, world, toVectorWorld, ForgeDirection.SOUTH, ForgeDirection.EAST)
val yNorthEast = FluidUtility.getAveragePercentageFilledForSides(classOf[TileTank], percentageFilled, world, toVectorWorld, ForgeDirection.NORTH, ForgeDirection.EAST)
val ySouthWest = FluidUtility.getAveragePercentageFilledForSides(classOf[TileTank], percentageFilled, world, toVectorWorld, ForgeDirection.SOUTH, ForgeDirection.WEST)
val yNorthWest = FluidUtility.getAveragePercentageFilledForSides(classOf[TileTank], percentageFilled, world, toVectorWorld, ForgeDirection.NORTH, ForgeDirection.WEST)
FluidRenderUtility.renderFluidTesselation(tank, ySouthEast, yNorthEast, ySouthWest, yNorthWest)
}
GL11.glPopMatrix()
}
GL11.glPopMatrix()
}
}
@SideOnly(Side.CLIENT)
override def renderInventory(itemStack: ItemStack)
{
super.renderInventory(itemStack)
GL11.glPushMatrix()
if (itemStack.getTagCompound != null && itemStack.getTagCompound.hasKey("fluid"))
{
renderInventoryFluid(0, 0, 0, FluidStack.loadFluidStackFromNBT(itemStack.getTagCompound.getCompoundTag("fluid")), fluidNode.getTank.getCapacity)
}
GL11.glPopMatrix()
}
@SideOnly(Side.CLIENT)
def renderInventoryFluid(x: Double, y: Double, z: Double, fluid: FluidStack, capacity: Int)
{
val tank = new FluidTank(fluid, capacity)
GL11.glPushMatrix()
GL11.glTranslated(0.02, 0.02, 0.02)
GL11.glScaled(0.92, 0.92, 0.92)
if (fluid != null)
{
GL11.glPushMatrix()
if (!fluid.getFluid.isGaseous)
{
val percentageFilled: Double = tank.getFluidAmount.toDouble / tank.getCapacity.toDouble
FluidRenderUtility.renderFluidTesselation(tank, percentageFilled, percentageFilled, percentageFilled, percentageFilled)
}
else
{
val filledPercentage: Double = fluid.amount.toDouble / capacity.toDouble
GL11.glPushAttrib(GL11.GL_ENABLE_BIT)
GL11.glEnable(GL11.GL_CULL_FACE)
GL11.glDisable(GL11.GL_LIGHTING)
GL11.glEnable(GL11.GL_BLEND)
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA)
val color: Color = new Color(fluid.getFluid.getColor)
RenderUtility.enableBlending()
GL11.glColor4d(color.getRed / 255f, color.getGreen / 255f, color.getBlue / 255f, if (fluid.getFluid.isGaseous) filledPercentage else 1)
RenderUtility.bind(FluidRenderUtility.getFluidSheet(fluid))
FluidRenderUtility.renderFluidTesselation(tank, 1, 1, 1, 1)
RenderUtility.disableBlending()
GL11.glPopAttrib()
}
GL11.glPopMatrix()
}
GL11.glPopMatrix()
}
def getRemovedItems(entity: EntityPlayer): List[ItemStack] =
{
val drops = new ArrayList[ItemStack]
val itemStack: ItemStack = new ItemStack(BasicContent.blockTank, 1, 0)
if (itemStack != null)
{
if (fluidNode != null && fluidNode.getFluid != null)
{
val stack: FluidStack = fluidNode.getFluid
if (stack != null)
{
if (itemStack.getTagCompound == null)
{
itemStack.setTagCompound(new NBTTagCompound)
}
drain(ForgeDirection.UNKNOWN, stack.amount, false)
itemStack.getTagCompound.setTag("fluid", stack.writeToNBT(new NBTTagCompound))
}
}
drops.add(itemStack)
}
return drops
}
}