Fluids in tanks now flow

This commit is contained in:
Calclavia 2014-11-07 12:27:31 +08:00
parent 28fa18f809
commit 427f2ba132
8 changed files with 88 additions and 81 deletions

View file

@ -3,7 +3,6 @@ package resonantinduction.archaic.fluid.grate
import java.util.{Collections, Comparator, HashMap, PriorityQueue}
import cpw.mods.fml.relauncher.{Side, SideOnly}
import io.netty.buffer.ByteBuf
import net.minecraft.block.material.Material
import net.minecraft.client.renderer.texture.IIconRegister
import net.minecraft.entity.player.EntityPlayer
@ -14,8 +13,6 @@ import net.minecraftforge.common.util.ForgeDirection
import net.minecraftforge.fluids.{Fluid, FluidContainerRegistry, FluidRegistry, FluidStack}
import resonant.api.IRotatable
import resonant.lib.config.Config
import resonant.lib.network.discriminator.PacketType
import resonant.lib.prefab.fluid.NodeFluid
import resonant.lib.transform.vector.Vector3
import resonant.lib.utility.FluidUtility
import resonantinduction.archaic.fluid.grate.TileGrate._
@ -54,7 +51,7 @@ object TileGrate
class TileGrate extends TileFluidProvider(Material.rock) with IRotatable
{
override protected val fluidNode = new NodePressure(this)
fluidNode = new NodePressure(this)
private var gratePath: GratePathfinder = _
private var fillOver: Boolean = true
isOpaqueCube = false
@ -93,30 +90,31 @@ class TileGrate extends TileFluidProvider(Material.rock) with IRotatable
override def update()
{
super.update()
if (!world.isRemote)
{
if (ticks % 10 == 0)
{
val pressure = fluidNode.pressure(getDirection)
val pressure = fluidNode.asInstanceOf[NodePressure].pressure(getDirection)
val blockEffect = Math.abs(pressure * grateEffectMultiplier).toInt
fluidNode.getPrimaryTank.setCapacity(Math.max(blockEffect * FluidContainerRegistry.BUCKET_VOLUME * grateDrainSpeedMultiplier, FluidContainerRegistry.BUCKET_VOLUME).toInt)
if (pressure > 0)
{
if (getFluidAmount >= FluidContainerRegistry.BUCKET_VOLUME)
if (fluidNode.getFluidAmount >= FluidContainerRegistry.BUCKET_VOLUME)
{
if (gratePath == null)
{
gratePath = new GratePathfinder(true)
gratePath.startFill(asVectorWorld, getTank.getFluid.getFluid.getID)
gratePath.startFill(asVectorWorld, fluidNode.getFluid.getFluid.getID)
}
val filledInWorld = gratePath.tryFill(getFluidAmount, blockEffect)
getTank.drain(filledInWorld, true)
val filledInWorld = gratePath.tryFill(fluidNode.getFluidAmount, blockEffect)
fluidNode.drain(filledInWorld, true)
}
}
else if (pressure < 0)
{
val maxDrain = getTank.getCapacity - getFluidAmount
val maxDrain = fluidNode.getCapacity - fluidNode.getFluidAmount
if (maxDrain > 0)
{
if (gratePath == null)
@ -129,7 +127,7 @@ class TileGrate extends TileFluidProvider(Material.rock) with IRotatable
}
if (gratePath != null && gratePath.tryPopulateDrainMap(blockEffect))
{
getTank.fill(gratePath.tryDrain(maxDrain, true), true)
fluidNode.fill(gratePath.tryDrain(maxDrain, true), true)
}
}
}
@ -142,7 +140,7 @@ class TileGrate extends TileFluidProvider(Material.rock) with IRotatable
this.gratePath = null
}
override def fill(from: ForgeDirection, resource: FluidStack, doFill: Boolean): Int = getTank.fill(resource, doFill)
override def fill(from: ForgeDirection, resource: FluidStack, doFill: Boolean): Int = fluidNode.fill(resource, doFill)
override def drain(from: ForgeDirection, resource: FluidStack, doDrain: Boolean): FluidStack =
{
@ -155,7 +153,7 @@ class TileGrate extends TileFluidProvider(Material.rock) with IRotatable
override def drain(from: ForgeDirection, maxDrain: Int, doDrain: Boolean): FluidStack =
{
getTank.drain(maxDrain, doDrain)
fluidNode.drain(maxDrain, doDrain)
}
protected override def configure(player: EntityPlayer, side: Int, hit: Vector3): Boolean =

View file

@ -1,46 +1,44 @@
package resonantinduction.archaic.fluid.gutter
import net.minecraftforge.common.util.ForgeDirection
import net.minecraftforge.fluids.Fluid
import net.minecraftforge.fluids.FluidStack
import resonantinduction.core.prefab.node.NodePressure
import resonantinduction.core.prefab.node.TileFluidProvider
import net.minecraftforge.fluids.{Fluid, FluidContainerRegistry, FluidStack}
import resonantinduction.core.prefab.node.{NodePressure, TileFluidProvider}
/**
* A node for fluid that follows pressure and gravity.
* @author Calclavia
*/
class NodePressureGravity(parent: TileFluidProvider) extends NodePressure(parent)
class NodePressureGravity(parent: TileFluidProvider, volume: Int = FluidContainerRegistry.BUCKET_VOLUME) extends NodePressure(parent, volume)
{
override def pressure(dir: ForgeDirection): Int =
override def pressure(dir: ForgeDirection): Int =
{
if (dir == ForgeDirection.UP)
{
if (dir eq ForgeDirection.UP)
{
return -2
}
if (dir eq ForgeDirection.DOWN)
{
return 2
}
return 0
return -2
}
if (dir == ForgeDirection.DOWN)
{
return 2
}
return 0
}
override def canFill(from: ForgeDirection, fluid: Fluid): Boolean =
{
return from != ForgeDirection.UP && !fluid.isGaseous
}
override def canFill(from: ForgeDirection, fluid: Fluid): Boolean =
{
return from != ForgeDirection.UP && !fluid.isGaseous
}
override def canDrain(from: ForgeDirection, fluid: Fluid): Boolean =
{
return from != ForgeDirection.UP && !fluid.isGaseous
}
override def canDrain(from: ForgeDirection, fluid: Fluid): Boolean =
{
return from != ForgeDirection.UP && !fluid.isGaseous
}
override def fill(from: ForgeDirection, resource: FluidStack, doFill: Boolean): Int =
override def fill(from: ForgeDirection, resource: FluidStack, doFill: Boolean): Int =
{
if (!resource.getFluid.isGaseous)
{
if (!resource.getFluid.isGaseous)
{
return super.fill(from, resource, doFill)
}
return 0
return super.fill(from, resource, doFill)
}
return 0
}
}

View file

@ -23,7 +23,7 @@ import resonant.lib.utility.FluidUtility
import resonant.lib.utility.inventory.InventoryUtility
import resonant.lib.wrapper.BitmaskWrapper._
import resonantinduction.core.Reference
import resonantinduction.core.prefab.node.TileFluidProvider
import resonantinduction.core.prefab.node.{NodePressure, TileFluidProvider}
object TileGutter
{
@ -38,7 +38,7 @@ object TileGutter
*/
class TileGutter extends TileFluidProvider(Material.rock)
{
override protected val fluidNode = new NodePressureGravity(this)
fluidNode = new NodePressureGravity(this)
textureName = "material_wood_surface"
isOpaqueCube = false
@ -77,24 +77,24 @@ class TileGutter extends TileFluidProvider(Material.rock)
override def collide(entity: Entity)
{
if (getTank.getFluidAmount > 0)
if (fluidNode.getFluidAmount > 0)
{
for (i <- 2 to 6)
{
val dir: ForgeDirection = ForgeDirection.getOrientation(i)
val pressure: Int = fluidNode.pressure(dir)
val pressure: Int = fluidNode.asInstanceOf[NodePressure].pressure(dir)
val pos: Vector3 = asVector3.add(dir)
val checkTile: TileEntity = pos.getTileEntity(world)
if (checkTile.isInstanceOf[TileGutter])
{
val deltaPressure: Int = pressure - checkTile.asInstanceOf[TileGutter].fluidNode.pressure(dir.getOpposite)
val deltaPressure: Int = pressure - checkTile.asInstanceOf[TileGutter].fluidNode.asInstanceOf[NodePressure].pressure(dir.getOpposite)
entity.motionX += 0.01 * dir.offsetX * deltaPressure
entity.motionY += 0.01 * dir.offsetY * deltaPressure
entity.motionZ += 0.01 * dir.offsetZ * deltaPressure
}
}
if (getTank.getFluid.getFluid.getTemperature >= 373)
if (fluidNode.getFluid.getFluid.getTemperature >= 373)
{
entity.setFire(5)
}
@ -174,7 +174,7 @@ class TileGutter extends TileFluidProvider(Material.rock)
if (world != null)
{
val tank: IFluidTank = getTank
val tank: IFluidTank = fluidNode
val percentageFilled = tank.getFluidAmount / tank.getCapacity.toDouble
if (percentageFilled > 0.1)

View file

@ -76,7 +76,7 @@ class ItemBlockTank(block: Block) extends ItemBlock(block: Block) with IFluidCon
val tile: TileEntity = world.getTileEntity(x, y, z)
if (tile.isInstanceOf[TileTank])
{
(tile.asInstanceOf[TileTank]).getTank.fill(getFluid(stack), true)
tile.asInstanceOf[TileTank].fluidNode.fill(getFluid(stack), true)
}
return true
}

View file

@ -10,7 +10,7 @@ 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.{FluidStack, FluidTank, IFluidTank}
import net.minecraftforge.fluids.{FluidContainerRegistry, FluidStack, FluidTank, IFluidTank}
import org.lwjgl.opengl.GL11
import resonant.api.IRemovable.ISneakPickup
import resonant.content.prefab.RenderConnectedTexture
@ -18,8 +18,9 @@ import resonant.lib.render.{FluidRenderUtility, RenderUtility}
import resonant.lib.transform.vector.Vector3
import resonant.lib.utility.FluidUtility
import resonantinduction.archaic.ArchaicContent
import resonantinduction.archaic.fluid.gutter.NodePressureGravity
import resonantinduction.core.Reference
import resonantinduction.core.prefab.node.{NodePressure, TileFluidProvider}
import resonantinduction.core.prefab.node.TileFluidProvider
/**
* Tile/Block class for basic Dynamic tanks
@ -28,19 +29,25 @@ import resonantinduction.core.prefab.node.{NodePressure, TileFluidProvider}
*/
class TileTank extends TileFluidProvider(Material.iron) with ISneakPickup with RenderConnectedTexture
{
override protected val fluidNode = new NodePressure(this)
edgeTexture = Reference.prefix + "tankEdge"
isOpaqueCube = false
normalRender = false
itemBlock = classOf[ItemBlockTank]
fluidNode = new NodePressureGravity(this, 16 * FluidContainerRegistry.BUCKET_VOLUME)
fluidNode.asInstanceOf[NodePressureGravity].maxFlowRate = FluidContainerRegistry.BUCKET_VOLUME
fluidNode.onFluidChanged = () => markUpdate()
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)
{
//TODO: Somehow, the connections are not updating until manual triggers
println(fluidNode.connections.size())
fluidNode.reconstruct()
return FluidUtility.playerActivatedFluidItem(world, xi, yi, zi, player, side)
}
@ -49,9 +56,9 @@ class TileTank extends TileFluidProvider(Material.iron) with ISneakPickup with R
override def getLightValue(access: IBlockAccess): Int =
{
if (getFluid != null && getFluid.getFluid != null)
if (fluidNode.getPrimaryTank.getFluid != null && fluidNode.getPrimaryTank.getFluid.getFluid != null)
{
return getFluid.getFluid.getLuminosity
return fluidNode.getPrimaryTank.getFluid.getFluid.getLuminosity
}
return super.getLightValue(access)
@ -60,7 +67,7 @@ class TileTank extends TileFluidProvider(Material.iron) with ISneakPickup with R
@SideOnly(Side.CLIENT)
override def renderDynamic(position: Vector3, frame: Float, pass: Int)
{
renderTankFluid(position.x, position.y, position.z, getFluid)
renderTankFluid(position.x, position.y, position.z, fluidNode.getPrimaryTank.getFluid)
}
/**
@ -79,7 +86,7 @@ class TileTank extends TileFluidProvider(Material.iron) with ISneakPickup with R
if (!fluid.getFluid.isGaseous)
{
GL11.glScaled(0.99, 0.99, 0.99)
val tank: IFluidTank = getTank
val tank: IFluidTank = fluidNode.getPrimaryTank
val percentageFilled: Double = tank.getFluidAmount.toDouble / tank.getCapacity.toDouble
val ySouthEast: Double = FluidUtility.getAveragePercentageFilledForSides(classOf[TileTank], percentageFilled, world, asVector3, ForgeDirection.SOUTH, ForgeDirection.EAST)
val yNorthEast: Double = FluidUtility.getAveragePercentageFilledForSides(classOf[TileTank], percentageFilled, world, asVector3, ForgeDirection.NORTH, ForgeDirection.EAST)
@ -150,9 +157,9 @@ class TileTank extends TileFluidProvider(Material.iron) with ISneakPickup with R
val itemStack: ItemStack = new ItemStack(ArchaicContent.blockTank, 1, 0)
if (itemStack != null)
{
if (getTank != null && getTank.getFluid != null)
if (fluidNode != null && fluidNode.getFluid != null)
{
val stack: FluidStack = getTank.getFluid
val stack: FluidStack = fluidNode.getFluid
if (stack != null)
{
if (itemStack.getTagCompound == null)

View file

@ -22,7 +22,7 @@ class WailaFluidTank extends IWailaDataProvider
val tile: TileEntity = accessor.getTileEntity
if (tile.isInstanceOf[TileTank])
{
val tank: IFluidTank = (tile.asInstanceOf[TileTank]).getTank
val tank: IFluidTank = tile.asInstanceOf[TileTank].fluidNode
if (tank != null && tank.getFluid != null)
{
currenttip.add(LanguageUtility.getLocal("info.waila.tank.fluid") + " " + tank.getFluid.getFluid.getLocalizedName)

View file

@ -3,6 +3,7 @@ package resonantinduction.core.prefab.node
import net.minecraftforge.common.util.ForgeDirection
import net.minecraftforge.fluids.{FluidContainerRegistry, IFluidHandler}
import resonant.api.grid.{INodeProvider, IUpdate}
import resonant.lib.grid.UpdateTicker
import resonant.lib.prefab.fluid.NodeFluid
import scala.collection.convert.wrapAll._
@ -21,28 +22,34 @@ class NodePressure(parent: INodeProvider, volume: Int = FluidContainerRegistry.B
var maxPressure = 100
private var _pressure: Int = 0
UpdateTicker.addUpdater(this)
def update(deltaTime: Double)
{
if (!world.isRemote)
{
updatePressure()
distribute()
distribute(deltaTime)
}
}
def distribute()
def distribute(deltaTime: Double)
{
val flowRate = (maxFlowRate * deltaTime).toInt
directionMap.foreach
{
case (handler: IFluidHandler, dir: ForgeDirection) =>
{
if (handler.isInstanceOf[NodePressure])
{
//"A" is this node. "B" is the other node
//It's another pressure node
val otherNode = handler.asInstanceOf[NodePressure]
val pressureA = pressure(dir)
val pressureB = otherNode.pressure(dir.getOpposite)
//High pressure to low
if (pressureA >= pressureB)
{
val tankA = getPrimaryTank
@ -53,15 +60,18 @@ class NodePressure(parent: INodeProvider, volume: Int = FluidContainerRegistry.B
if (fluidA != null)
{
val amountA: Int = fluidA.amount
val amountA = fluidA.amount
if (amountA > 0)
{
val tankB = otherNode.getPrimaryTank
if (tankB != null)
{
val amountB: Int = tankB.getFluidAmount
var quantity: Int = Math.max(if (pressureA > pressureB) (pressureA - pressureB) * maxFlowRate else 0, Math.min((amountA - amountB) / 2, maxFlowRate))
val amountB = tankB.getFluidAmount
var quantity = Math.max(if (pressureA > pressureB) (pressureA - pressureB) * flowRate else Math.min((amountA - amountB) / 2, flowRate), Math.min((amountA - amountB) / 2, flowRate))
quantity = Math.min(Math.min(quantity, tankB.getCapacity - amountB), amountA)
if (quantity > 0)
{
val drainStack = drain(dir.getOpposite, quantity, false)
@ -80,9 +90,9 @@ class NodePressure(parent: INodeProvider, volume: Int = FluidContainerRegistry.B
{
//It's a fluid handler.
val pressure = this.pressure(dir)
val tankPressure = 0
val tankPressure = 0
val sourceTank = getPrimaryTank
val transferAmount = (Math.max(pressure, tankPressure) - Math.min(pressure, tankPressure)) * maxFlowRate
val transferAmount = (Math.max(pressure, tankPressure) - Math.min(pressure, tankPressure)) * flowRate
if (pressure > tankPressure)
{
@ -154,7 +164,7 @@ class NodePressure(parent: INodeProvider, volume: Int = FluidContainerRegistry.B
this._pressure = pressure
}
def canUpdate = true
def canUpdate = !isInvalid
def continueUpdate = true
def continueUpdate = !isInvalid
}

View file

@ -20,23 +20,19 @@ import resonant.lib.wrapper.BitmaskWrapper._
*/
abstract class TileFluidProvider(material: Material) extends TileAdvanced(material) with TSpatialNodeProvider with IFluidHandler with TPacketReceiver with TPacketSender
{
protected val fluidNode: NodeFluid
private var _fluidNode: NodeFluid = null
protected var colorID: Int = 0
protected var clientRenderMask = 0x3F
override def start()
def fluidNode = _fluidNode
def fluidNode_=(newNode: NodeFluid)
{
fluidNode.onConnectionChanged = () => if(!isInvalid) sendPacket(1)
_fluidNode = newNode
fluidNode.onConnectionChanged = () => if (!isInvalid) sendPacket(1)
nodes.add(fluidNode)
super.start()
}
def getFluid: FluidStack = getTank.getFluid
def getFluidCapacity: Int = getTank.getCapacity
def getTank: IFluidTank = fluidNode
override def write(buf: ByteBuf, id: Int)
{
super.write(buf, id)
@ -104,6 +100,4 @@ abstract class TileFluidProvider(material: Material) extends TileAdvanced(materi
override def fill(from: ForgeDirection, resource: FluidStack, doFill: Boolean): Int = fluidNode.fill(from, resource, doFill)
override def getTankInfo(from: ForgeDirection): Array[FluidTankInfo] = fluidNode.getTankInfo(from)
def getFluidAmount: Int = fluidNode.getFluidAmount
}