electrodynamics/src/main/scala/resonantinduction/mechanical/fluid/pipe/PartPipe.scala
2014-09-14 14:47:06 +08:00

175 lines
No EOL
4 KiB
Scala

package resonantinduction.mechanical.fluid.pipe
import codechicken.lib.data.MCDataInput
import codechicken.lib.render.CCRenderState
import codechicken.lib.vec.Vector3
import codechicken.multipart.{TNormalOcclusion, TSlottedPart}
import cpw.mods.fml.relauncher.{Side, SideOnly}
import net.minecraft.client.renderer.RenderBlocks
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.ForgeDirection
import net.minecraftforge.fluids._
import resonant.lib.`type`.EvictingList
import resonantinduction.core.prefab.part.connector.{PartFramedNode, TColorable, TMaterial}
import resonantinduction.mechanical.Mechanical
import resonantinduction.mechanical.fluid.pipe.PipeMaterials.PipeMaterial
/**
* Fluid transport pipe
*
* @author Calclavia
*/
class PartPipe extends PartFramedNode with TMaterial[PipeMaterial] with TColorable with TSlottedPart with TNormalOcclusion with IFluidHandler
{
protected final val tank: FluidTank = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME)
/**
* Computes the average fluid for client to render.
*/
private val averageTankData = new EvictingList[Integer](20)
private var markPacket: Boolean = true
setNode(new PipePressureNode(this))
def preparePlacement(meta: Int)
{
setMaterial(meta)
}
def setMaterial(i: Int)
{
material = PipeMaterials(i).asInstanceOf[PipeMaterial]
}
def getMaterialID: Int = material.id
override def update()
{
super.update()
averageTankData.add(tank.getFluidAmount)
if (!world.isRemote && markPacket)
{
sendFluidUpdate
markPacket = false
}
}
/**
* Sends fluid level to the client to be used in the renderer
*/
def sendFluidUpdate
{
val nbt = new NBTTagCompound
var averageAmount: Int = 0
if (averageTankData.size > 0)
{
for (i <- 0 until averageTankData.size)
{
{
averageAmount += averageTankData.get(i)
}
}
averageAmount /= averageTankData.size
}
val tempTank: FluidTank = if (tank.getFluid != null) new FluidTank(tank.getFluid.getFluid, averageAmount, tank.getCapacity) else new FluidTank(tank.getCapacity)
tempTank.writeToNBT(nbt)
tile.getWriteStream(this).writeByte(3).writeInt(tank.getCapacity).writeNBTTagCompound(nbt)
}
override def read(packet: MCDataInput, packetID: Int)
{
if (packetID == 3)
{
tank.setCapacity(packet.readInt)
tank.readFromNBT(packet.readNBTTagCompound)
}
else
{
super.read(packet, packetID)
}
}
@SideOnly(Side.CLIENT)
override def renderDynamic(pos: Vector3, frame: Float, pass: Int)
{
RenderPipe.INSTANCE.render(this, pos.x, pos.y, pos.z, frame)
}
def getItem: ItemStack =
{
return new ItemStack(Mechanical.itemPipe, 1, getMaterialID)
}
def fill(from: ForgeDirection, resource: FluidStack, doFill: Boolean): Int =
{
if (!world.isRemote)
{
if (doFill)
{
markPacket = true
}
return tank.fill(resource, doFill)
}
return 0
}
def drain(from: ForgeDirection, resource: FluidStack, doDrain: Boolean): FluidStack =
{
return drain(from, resource.amount, doDrain)
}
def drain(from: ForgeDirection, maxDrain: Int, doDrain: Boolean): FluidStack =
{
if (!world.isRemote)
{
if (doDrain)
{
markPacket = true
}
return tank.drain(maxDrain, doDrain)
}
return null
}
def canFill(from: ForgeDirection, fluid: Fluid): Boolean =
{
return true
}
def canDrain(from: ForgeDirection, fluid: Fluid): Boolean =
{
return true
}
def getTankInfo(from: ForgeDirection): Array[FluidTankInfo] =
{
return Array[FluidTankInfo](tank.getInfo)
}
override def drawBreaking(renderBlocks: RenderBlocks)
{
CCRenderState.reset()
}
override def save(nbt: NBTTagCompound)
{
super.save(nbt)
tank.writeToNBT(nbt)
}
override def load(nbt: NBTTagCompound)
{
super.load(nbt)
tank.readFromNBT(nbt)
}
override def getSlotMask: Int =
{
return 0
}
}