215 lines
7.6 KiB
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
|
|
}
|
|
}
|