Added IFluidHandler capability support to tank analytics.

For #2063.
This commit is contained in:
Vexatos 2016-11-19 23:41:34 +01:00
parent 4a47b04e56
commit b7e03cae44
3 changed files with 31 additions and 9 deletions

View File

@ -14,7 +14,7 @@ trait TankWorldControl extends TankAware with WorldAware with SideRestricted {
val side = checkSideForAction(args, 0) val side = checkSideForAction(args, 0)
fluidInTank(selectedTank) match { fluidInTank(selectedTank) match {
case Some(stack) => 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 Some(handler) => result(Option(handler.getTankInfo(side.getOpposite)).exists(_.exists(other => stack.isFluidEqual(other.fluid))))
case _ => result(false) case _ => result(false)
} }
@ -31,7 +31,7 @@ trait TankWorldControl extends TankAware with WorldAware with SideRestricted {
val space = tank.getCapacity - tank.getFluidAmount val space = tank.getCapacity - tank.getFluidAmount
val amount = math.min(count, space) val amount = math.min(count, space)
if (count < 1 || amount > 0) { if (count < 1 || amount > 0) {
FluidUtils.fluidHandlerAt(position.offset(facing)) match { FluidUtils.fluidHandlerAt(position.offset(facing), facing.getOpposite) match {
case Some(handler) => case Some(handler) =>
tank.getFluid match { tank.getFluid match {
case stack: FluidStack => case stack: FluidStack =>
@ -61,7 +61,7 @@ trait TankWorldControl extends TankAware with WorldAware with SideRestricted {
case Some(tank) => case Some(tank) =>
val amount = math.min(count, tank.getFluidAmount) val amount = math.min(count, tank.getFluidAmount)
if (count < 1 || amount > 0) { if (count < 1 || amount > 0) {
FluidUtils.fluidHandlerAt(position.offset(facing)) match { FluidUtils.fluidHandlerAt(position.offset(facing), facing.getOpposite) match {
case Some(handler) => case Some(handler) =>
tank.getFluid match { tank.getFluid match {
case stack: FluidStack => case stack: FluidStack =>

View File

@ -12,7 +12,7 @@ trait WorldTankAnalytics extends WorldAware with SideRestricted {
def getTankLevel(context: Context, args: Arguments): Array[AnyRef] = { def getTankLevel(context: Context, args: Arguments): Array[AnyRef] = {
val facing = checkSideForAction(args, 0) val facing = checkSideForAction(args, 0)
FluidUtils.fluidHandlerAt(position.offset(facing)) match { FluidUtils.fluidHandlerAt(position.offset(facing), facing.getOpposite) match {
case Some(handler) => case Some(handler) =>
result(handler.getTankInfo(facing.getOpposite).map(info => Option(info.fluid).fold(0)(_.amount)).sum) result(handler.getTankInfo(facing.getOpposite).map(info => Option(info.fluid).fold(0)(_.amount)).sum)
case _ => result(Unit, "no tank") 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.""") @Callback(doc = """function(side:number):number -- Get the capacity of the tank on the specified side.""")
def getTankCapacity(context: Context, args: Arguments): Array[AnyRef] = { def getTankCapacity(context: Context, args: Arguments): Array[AnyRef] = {
val facing = checkSideForAction(args, 0) val facing = checkSideForAction(args, 0)
FluidUtils.fluidHandlerAt(position.offset(facing)) match { FluidUtils.fluidHandlerAt(position.offset(facing), facing.getOpposite) match {
case Some(handler) => case Some(handler) =>
result(handler.getTankInfo(facing.getOpposite).map(_.capacity).foldLeft(0)((max, capacity) => math.max(max, capacity))) result(handler.getTankInfo(facing.getOpposite).map(_.capacity).foldLeft(0)((max, capacity) => math.max(max, capacity)))
case _ => result(Unit, "no tank") 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.""") @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) { def getFluidInTank(context: Context, args: Arguments): Array[AnyRef] = if (Settings.get.allowItemStackInspection) {
val facing = checkSideForAction(args, 0) val facing = checkSideForAction(args, 0)
FluidUtils.fluidHandlerAt(position.offset(facing)) match { FluidUtils.fluidHandlerAt(position.offset(facing), facing.getOpposite) match {
case Some(handler) => case Some(handler) =>
result(handler.getTankInfo(facing.getOpposite)) result(handler.getTankInfo(facing.getOpposite))
case _ => result(Unit, "no tank") case _ => result(Unit, "no tank")

View File

@ -7,6 +7,7 @@ import net.minecraft.block.BlockDynamicLiquid
import net.minecraft.block.BlockLiquid import net.minecraft.block.BlockLiquid
import net.minecraft.block.BlockStaticLiquid import net.minecraft.block.BlockStaticLiquid
import net.minecraft.init.Blocks import net.minecraft.init.Blocks
import net.minecraft.tileentity.TileEntity
import net.minecraft.util.EnumFacing import net.minecraft.util.EnumFacing
import net.minecraftforge.fluids.Fluid import net.minecraftforge.fluids.Fluid
import net.minecraftforge.fluids.FluidContainerRegistry import net.minecraftforge.fluids.FluidContainerRegistry
@ -16,6 +17,8 @@ import net.minecraftforge.fluids.FluidTank
import net.minecraftforge.fluids.FluidTankInfo import net.minecraftforge.fluids.FluidTankInfo
import net.minecraftforge.fluids.IFluidBlock import net.minecraftforge.fluids.IFluidBlock
import net.minecraftforge.fluids.IFluidHandler import net.minecraftforge.fluids.IFluidHandler
import net.minecraftforge.fluids.capability
import net.minecraftforge.fluids.capability.CapabilityFluidHandler
object FluidUtils { object FluidUtils {
/** /**
@ -23,9 +26,14 @@ object FluidUtils {
* <p/> * <p/>
* This performs special handling for in-world liquids. * 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 Some(world) if world.blockExists(position) => world.getTileEntity(position) match {
case handler: IFluidHandler => Option(handler) 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 _ => Option(new GenericBlockWrapper(position))
} }
case _ => None case _ => None
@ -54,8 +62,8 @@ object FluidUtils {
* cases such as fluid blocks. * cases such as fluid blocks.
*/ */
def transferBetweenFluidHandlersAt(sourcePos: BlockPosition, sourceSide: EnumFacing, sinkPos: BlockPosition, sinkSide: EnumFacing, limit: Int = FluidContainerRegistry.BUCKET_VOLUME) = def transferBetweenFluidHandlersAt(sourcePos: BlockPosition, sourceSide: EnumFacing, sinkPos: BlockPosition, sinkSide: EnumFacing, limit: Int = FluidContainerRegistry.BUCKET_VOLUME) =
fluidHandlerAt(sourcePos).fold(0)(source => fluidHandlerAt(sourcePos, sourceSide).fold(0)(source =>
fluidHandlerAt(sinkPos).fold(0)(sink => fluidHandlerAt(sinkPos, sinkSide).fold(0)(sink =>
transferBetweenFluidHandlers(source, sourceSide, sink, sinkSide, limit))) transferBetweenFluidHandlers(source, sourceSide, sink, sinkSide, limit)))
/** /**
@ -173,4 +181,18 @@ object FluidUtils {
override def getTankInfo(from: EnumFacing): Array[FluidTankInfo] = Array.empty 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))
}
} }