diff --git a/src/main/scala/li/cil/oc/server/component/traits/TankWorldControl.scala b/src/main/scala/li/cil/oc/server/component/traits/TankWorldControl.scala index ee6254298..42024bf20 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/TankWorldControl.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/TankWorldControl.scala @@ -14,7 +14,7 @@ trait TankWorldControl extends TankAware with WorldAware with SideRestricted { val side = checkSideForAction(args, 0) fluidInTank(selectedTank) match { case Some(stack) => - FluidUtils.fluidHandlerAt(position.offset(side)) match { + FluidUtils.fluidHandlerAt(position.offset(side), side.getOpposite) match { case Some(handler) => result(Option(handler.getTankInfo(side.getOpposite)).exists(_.exists(other => stack.isFluidEqual(other.fluid)))) case _ => result(false) } @@ -31,7 +31,7 @@ trait TankWorldControl extends TankAware with WorldAware with SideRestricted { val space = tank.getCapacity - tank.getFluidAmount val amount = math.min(count, space) if (count < 1 || amount > 0) { - FluidUtils.fluidHandlerAt(position.offset(facing)) match { + FluidUtils.fluidHandlerAt(position.offset(facing), facing.getOpposite) match { case Some(handler) => tank.getFluid match { case stack: FluidStack => @@ -61,7 +61,7 @@ trait TankWorldControl extends TankAware with WorldAware with SideRestricted { case Some(tank) => val amount = math.min(count, tank.getFluidAmount) if (count < 1 || amount > 0) { - FluidUtils.fluidHandlerAt(position.offset(facing)) match { + FluidUtils.fluidHandlerAt(position.offset(facing), facing.getOpposite) match { case Some(handler) => tank.getFluid match { case stack: FluidStack => diff --git a/src/main/scala/li/cil/oc/server/component/traits/WorldTankAnalytics.scala b/src/main/scala/li/cil/oc/server/component/traits/WorldTankAnalytics.scala index ec7950223..711f958b9 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/WorldTankAnalytics.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/WorldTankAnalytics.scala @@ -12,7 +12,7 @@ trait WorldTankAnalytics extends WorldAware with SideRestricted { def getTankLevel(context: Context, args: Arguments): Array[AnyRef] = { val facing = checkSideForAction(args, 0) - FluidUtils.fluidHandlerAt(position.offset(facing)) match { + FluidUtils.fluidHandlerAt(position.offset(facing), facing.getOpposite) match { case Some(handler) => result(handler.getTankInfo(facing.getOpposite).map(info => Option(info.fluid).fold(0)(_.amount)).sum) case _ => result(Unit, "no tank") @@ -22,7 +22,7 @@ trait WorldTankAnalytics extends WorldAware with SideRestricted { @Callback(doc = """function(side:number):number -- Get the capacity of the tank on the specified side.""") def getTankCapacity(context: Context, args: Arguments): Array[AnyRef] = { val facing = checkSideForAction(args, 0) - FluidUtils.fluidHandlerAt(position.offset(facing)) match { + FluidUtils.fluidHandlerAt(position.offset(facing), facing.getOpposite) match { case Some(handler) => result(handler.getTankInfo(facing.getOpposite).map(_.capacity).foldLeft(0)((max, capacity) => math.max(max, capacity))) case _ => result(Unit, "no tank") @@ -32,7 +32,7 @@ trait WorldTankAnalytics extends WorldAware with SideRestricted { @Callback(doc = """function(side:number):table -- Get a description of the fluid in the the tank on the specified side.""") def getFluidInTank(context: Context, args: Arguments): Array[AnyRef] = if (Settings.get.allowItemStackInspection) { val facing = checkSideForAction(args, 0) - FluidUtils.fluidHandlerAt(position.offset(facing)) match { + FluidUtils.fluidHandlerAt(position.offset(facing), facing.getOpposite) match { case Some(handler) => result(handler.getTankInfo(facing.getOpposite)) case _ => result(Unit, "no tank") diff --git a/src/main/scala/li/cil/oc/util/FluidUtils.scala b/src/main/scala/li/cil/oc/util/FluidUtils.scala index ba6945c26..e890a4b58 100644 --- a/src/main/scala/li/cil/oc/util/FluidUtils.scala +++ b/src/main/scala/li/cil/oc/util/FluidUtils.scala @@ -7,6 +7,7 @@ import net.minecraft.block.BlockDynamicLiquid import net.minecraft.block.BlockLiquid import net.minecraft.block.BlockStaticLiquid import net.minecraft.init.Blocks +import net.minecraft.tileentity.TileEntity import net.minecraft.util.EnumFacing import net.minecraftforge.fluids.Fluid import net.minecraftforge.fluids.FluidContainerRegistry @@ -16,6 +17,8 @@ import net.minecraftforge.fluids.FluidTank import net.minecraftforge.fluids.FluidTankInfo import net.minecraftforge.fluids.IFluidBlock import net.minecraftforge.fluids.IFluidHandler +import net.minecraftforge.fluids.capability +import net.minecraftforge.fluids.capability.CapabilityFluidHandler object FluidUtils { /** @@ -23,9 +26,14 @@ object FluidUtils { *

* This performs special handling for in-world liquids. */ - def fluidHandlerAt(position: BlockPosition): Option[IFluidHandler] = position.world match { + def fluidHandlerAt(position: BlockPosition, side: EnumFacing): Option[IFluidHandler] = position.world match { case Some(world) if world.blockExists(position) => world.getTileEntity(position) match { case handler: IFluidHandler => Option(handler) + case t: TileEntity if t.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side) => + t.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side) match { + case handler: capability.IFluidHandler => Option(new HandlerCapabilityWrapper(position, handler)) + case _ => Option(new GenericBlockWrapper(position)) + } case _ => Option(new GenericBlockWrapper(position)) } case _ => None @@ -54,8 +62,8 @@ object FluidUtils { * cases such as fluid blocks. */ def transferBetweenFluidHandlersAt(sourcePos: BlockPosition, sourceSide: EnumFacing, sinkPos: BlockPosition, sinkSide: EnumFacing, limit: Int = FluidContainerRegistry.BUCKET_VOLUME) = - fluidHandlerAt(sourcePos).fold(0)(source => - fluidHandlerAt(sinkPos).fold(0)(sink => + fluidHandlerAt(sourcePos, sourceSide).fold(0)(source => + fluidHandlerAt(sinkPos, sinkSide).fold(0)(sink => transferBetweenFluidHandlers(source, sourceSide, sink, sinkSide, limit))) /** @@ -173,4 +181,18 @@ object FluidUtils { override def getTankInfo(from: EnumFacing): Array[FluidTankInfo] = Array.empty } + private class HandlerCapabilityWrapper(val position: BlockPosition, val handler: capability.IFluidHandler) extends IFluidHandler { + override def drain(from: EnumFacing, resource: FluidStack, doDrain: Boolean): FluidStack = handler.drain(resource, doDrain) + + override def drain(from: EnumFacing, maxDrain: Int, doDrain: Boolean): FluidStack = handler.drain(maxDrain, doDrain) + + override def canFill(from: EnumFacing, fluid: Fluid): Boolean = handler.getTankProperties.exists(_.canFill) + + override def canDrain(from: EnumFacing, fluid: Fluid): Boolean = handler.getTankProperties.exists(_.canDrain) + + override def fill(from: EnumFacing, resource: FluidStack, doFill: Boolean): Int = handler.fill(resource, doFill) + + override def getTankInfo(from: EnumFacing): Array[FluidTankInfo] = handler.getTankProperties.map(f => new FluidTankInfo(f.getContents, f.getCapacity)) + } + }