diff --git a/src/main/java/com/glodblock/github/common/tile/TileCertusQuartzTank.java b/src/main/java/com/glodblock/github/common/tile/TileCertusQuartzTank.java index 53911ab2..63d27030 100644 --- a/src/main/java/com/glodblock/github/common/tile/TileCertusQuartzTank.java +++ b/src/main/java/com/glodblock/github/common/tile/TileCertusQuartzTank.java @@ -1,14 +1,17 @@ package com.glodblock.github.common.tile; +import net.minecraft.block.Block; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.fluids.*; import com.glodblock.github.loader.ChannelLoader; +import com.glodblock.github.util.BlockPos; public class TileCertusQuartzTank extends TileEntity implements IFluidHandler { @@ -26,6 +29,7 @@ public class TileCertusQuartzTank extends TileEntity implements IFluidHandler { return this; } }; + private boolean hasUpdate; @Override public boolean canDrain(ForgeDirection from, Fluid fluid) { @@ -191,6 +195,40 @@ public class TileCertusQuartzTank extends TileEntity implements IFluidHandler { return (float) this.tank.getFluidAmount() / this.tank.getCapacity(); } + private void onComparatorUpdate(World world, int x, int y, int z, Block block) { + world.func_147453_f(x, y, z, block); + } + + @Override + public void updateEntity() { + super.updateEntity(); + if (this.tank.getFluid() != null) { + TileCertusQuartzTank below = getTankBelow(this); + if (below != null) { + FluidStack filled = this.tank.getFluid().copy(); + filled.amount = below.fill(this.tank.getFluid(), true, true); + if (filled.amount >= 0) { + this.drain(filled, true, true); + this.hasUpdate = true; + below.hasUpdate = true; + } + } + } + + if (this.hasUpdate) { + onComparatorUpdate(this.worldObj, this.xCoord, this.yCoord, this.zCoord, this.getBlockType()); + this.hasUpdate = false; + } + } + + private TileCertusQuartzTank getTankBelow(TileEntity tile) { + TileEntity tank = new BlockPos(tile).getOffSet(0, -1, 0).getTileEntity(); + if (tank != null && tank instanceof TileCertusQuartzTank) { + return (TileCertusQuartzTank) tank; + } + return null; + } + public FluidTankInfo[] getTankInfo(boolean goToMainTank) { if (!goToMainTank) return new FluidTankInfo[] { this.tank.getInfo() }; @@ -212,12 +250,12 @@ public class TileCertusQuartzTank extends TileEntity implements IFluidHandler { break; } - yOff = 0; - offTE = this.worldObj.getTileEntity(this.xCoord, this.yCoord + yOff, this.zCoord); + yOff -= 1; + offTE = this.worldObj.getTileEntity(this.xCoord, this.yCoord - yOff, this.zCoord); while (true) { if (offTE instanceof TileCertusQuartzTank) { mainTank = (TileCertusQuartzTank) offTE; - if (mainTank.getFluid() == null || mainTank.getFluid() == getFluid()) { + if (mainTank.getFluid() == null || getFluid() == null || mainTank.getFluid() == getFluid()) { FluidTankInfo info = mainTank.getTankInfo(false)[0]; if (info != null) { capacity += info.capacity; @@ -226,8 +264,7 @@ public class TileCertusQuartzTank extends TileEntity implements IFluidHandler { if (info.fluid.getFluid() != null) fluid = info.fluid.getFluid(); } } - yOff++; - offTE = this.worldObj.getTileEntity(this.xCoord, this.yCoord + yOff, this.zCoord); + offTE = new BlockPos(offTE).getOffSet(0, 1, 0).getTileEntity(); continue; } } @@ -274,4 +311,8 @@ public class TileCertusQuartzTank extends TileEntity implements IFluidHandler { public void writeToNBTWithoutCoords(NBTTagCompound tag) { this.tank.writeToNBT(tag); } + + public FluidTankInfo[] getInternalFluid() { + return this.getTankInfo(true); + } } diff --git a/src/main/java/com/glodblock/github/common/tile/TileFluidPacketDecoder.java b/src/main/java/com/glodblock/github/common/tile/TileFluidPacketDecoder.java index 0500fd32..cdabb33e 100644 --- a/src/main/java/com/glodblock/github/common/tile/TileFluidPacketDecoder.java +++ b/src/main/java/com/glodblock/github/common/tile/TileFluidPacketDecoder.java @@ -4,7 +4,8 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.fluids.*; import appeng.api.networking.GridFlags; import appeng.api.networking.IGridNode; @@ -30,7 +31,8 @@ import appeng.util.item.AEFluidStack; import com.glodblock.github.common.item.ItemFluidPacket; -public class TileFluidPacketDecoder extends AENetworkTile implements IGridTickable, IAEAppEngInventory, IInventory { +public class TileFluidPacketDecoder extends AENetworkTile + implements IGridTickable, IAEAppEngInventory, IInventory, IFluidHandler { private final AppEngInternalInventory inventory = new AppEngInternalInventory(this, 1); private final BaseActionSource ownActionSource = new MachineSource(this); @@ -164,4 +166,65 @@ public class TileFluidPacketDecoder extends AENetworkTile implements IGridTickab public boolean isItemValidForSlot(int slot, ItemStack stack) { return stack.getItem() instanceof ItemFluidPacket; } + + @Override + public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { + return 0; + } + + @Override + public FluidStack drain(ForgeDirection from, FluidStack requestFluid, boolean doDrain) { + return this.drain(requestFluid, doDrain); + } + + private FluidStack drain(FluidStack requestFluid, boolean doDrain) { + if (requestFluid == null || requestFluid.amount <= 0) return null; + ItemStack fluidPacket = this.inventory.getStackInSlot(0); + if (fluidPacket != null) { + FluidStack fs = ItemFluidPacket.getFluidStack(fluidPacket); + if (fs.isFluidEqual(requestFluid)) { + if (fs.amount > requestFluid.amount) { + fs.amount -= requestFluid.amount; + if (doDrain) this.inventory.setInventorySlotContents(0, ItemFluidPacket.newStack(fs)); + return requestFluid; + } else { + if (doDrain) this.inventory.setInventorySlotContents(0, null); + return fs; + } + } + } + return null; + } + + @Override + public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { + ItemStack fluidPacket = this.inventory.getStackInSlot(0); + if (fluidPacket != null) { + FluidStack requestFluid = ItemFluidPacket.getFluidStack(fluidPacket); + requestFluid.amount = maxDrain; + return this.drain(requestFluid, doDrain); + } + return null; + } + + @Override + public boolean canFill(ForgeDirection from, Fluid fluid) { + return false; + } + + @Override + public boolean canDrain(ForgeDirection from, Fluid fluid) { + return true; + } + + @Override + public FluidTankInfo[] getTankInfo(ForgeDirection from) { + ItemStack fluidPacket = this.inventory.getStackInSlot(0); + if (fluidPacket == null) { + return new FluidTankInfo[0]; + } else { + FluidStack fs = ItemFluidPacket.getFluidStack(fluidPacket); + return new FluidTankInfo[] { new FluidTankInfo(fs, fs.amount) }; + } + } } diff --git a/src/main/java/com/glodblock/github/crossmod/waila/Tooltip.java b/src/main/java/com/glodblock/github/crossmod/waila/Tooltip.java index eba29442..a1a9c267 100644 --- a/src/main/java/com/glodblock/github/crossmod/waila/Tooltip.java +++ b/src/main/java/com/glodblock/github/crossmod/waila/Tooltip.java @@ -15,6 +15,14 @@ public class Tooltip { return String.format("%s: %s mB", name, NumberFormat.getInstance().format(amount)); } + public static String fluidFormat(String name, long amount, long capacity) { + return String.format( + "%s: %s mB / %s mB", + name, + NumberFormat.getInstance().format(amount), + NumberFormat.getInstance().format(capacity)); + } + public static String partFluidBusFormat(int amount) { return String .format("%s: %s mB/t", I18n.format(NameConst.WAILA_SPEED), NumberFormat.getInstance().format(amount)); diff --git a/src/main/java/com/glodblock/github/crossmod/waila/VanillaTileWailaDataProvider.java b/src/main/java/com/glodblock/github/crossmod/waila/VanillaTileWailaDataProvider.java new file mode 100644 index 00000000..b4df57d8 --- /dev/null +++ b/src/main/java/com/glodblock/github/crossmod/waila/VanillaTileWailaDataProvider.java @@ -0,0 +1,71 @@ +package com.glodblock.github.crossmod.waila; + +import java.util.List; + +import mcp.mobius.waila.api.IWailaConfigHandler; +import mcp.mobius.waila.api.IWailaDataAccessor; +import mcp.mobius.waila.api.IWailaDataProvider; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +import com.glodblock.github.crossmod.waila.vanilla.FluidInvWailaDataProvider; +import com.google.common.collect.Lists; + +public class VanillaTileWailaDataProvider implements IWailaDataProvider { + + private final List providers; + + public VanillaTileWailaDataProvider() { + final IWailaDataProvider fluidInv = new FluidInvWailaDataProvider(); + this.providers = Lists.newArrayList(fluidInv); + } + + @Override + public ItemStack getWailaStack(final IWailaDataAccessor accessor, final IWailaConfigHandler config) { + return null; + } + + @Override + public List getWailaHead(final ItemStack itemStack, final List currentToolTip, + final IWailaDataAccessor accessor, final IWailaConfigHandler config) { + for (final IWailaDataProvider provider : this.providers) { + provider.getWailaHead(itemStack, currentToolTip, accessor, config); + } + + return currentToolTip; + } + + @Override + public List getWailaBody(final ItemStack itemStack, final List currentToolTip, + final IWailaDataAccessor accessor, final IWailaConfigHandler config) { + for (final IWailaDataProvider provider : this.providers) { + provider.getWailaBody(itemStack, currentToolTip, accessor, config); + } + + return currentToolTip; + } + + @Override + public List getWailaTail(final ItemStack itemStack, final List currentToolTip, + final IWailaDataAccessor accessor, final IWailaConfigHandler config) { + for (final IWailaDataProvider provider : this.providers) { + provider.getWailaTail(itemStack, currentToolTip, accessor, config); + } + + return currentToolTip; + } + + @Override + public NBTTagCompound getNBTData(final EntityPlayerMP player, final TileEntity te, final NBTTagCompound tag, + final World world, final int x, final int y, final int z) { + for (final IWailaDataProvider provider : this.providers) { + provider.getNBTData(player, te, tag, world, x, y, z); + } + + return tag; + } +} diff --git a/src/main/java/com/glodblock/github/crossmod/waila/WailaInit.java b/src/main/java/com/glodblock/github/crossmod/waila/WailaInit.java index 70186a9a..f7f56f1f 100644 --- a/src/main/java/com/glodblock/github/crossmod/waila/WailaInit.java +++ b/src/main/java/com/glodblock/github/crossmod/waila/WailaInit.java @@ -2,6 +2,9 @@ package com.glodblock.github.crossmod.waila; import mcp.mobius.waila.api.IWailaDataProvider; import mcp.mobius.waila.api.IWailaRegistrar; + +import net.minecraft.tileentity.TileEntity; + import appeng.api.parts.IPartHost; import appeng.tile.AEBaseTile; import appeng.util.Platform; @@ -23,5 +26,10 @@ public class WailaInit { final IWailaDataProvider tile = new TileWailaDataProvider(); registrar.registerBodyProvider(tile, AEBaseTile.class); registrar.registerNBTProvider(tile, AEBaseTile.class); + + final IWailaDataProvider vanillaTile = new VanillaTileWailaDataProvider(); + registrar.registerBodyProvider(vanillaTile, TileEntity.class); + registrar.registerNBTProvider(vanillaTile, TileEntity.class); + } } diff --git a/src/main/java/com/glodblock/github/crossmod/waila/vanilla/FluidInvWailaDataProvider.java b/src/main/java/com/glodblock/github/crossmod/waila/vanilla/FluidInvWailaDataProvider.java new file mode 100644 index 00000000..7b0f413d --- /dev/null +++ b/src/main/java/com/glodblock/github/crossmod/waila/vanilla/FluidInvWailaDataProvider.java @@ -0,0 +1,51 @@ +package com.glodblock.github.crossmod.waila.vanilla; + +import java.util.List; + +import mcp.mobius.waila.api.IWailaConfigHandler; +import mcp.mobius.waila.api.IWailaDataAccessor; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidTankInfo; + +import appeng.integration.modules.waila.BaseWailaDataProvider; + +import com.glodblock.github.common.tile.TileCertusQuartzTank; +import com.glodblock.github.crossmod.waila.Tooltip; +import com.glodblock.github.util.Util; + +public class FluidInvWailaDataProvider extends BaseWailaDataProvider { + + @Override + public List getWailaBody(final ItemStack itemStack, final List currentToolTip, + final IWailaDataAccessor accessor, final IWailaConfigHandler config) { + final TileEntity te = accessor.getTileEntity(); + if (te instanceof TileCertusQuartzTank) { + if (accessor.getNBTData().hasKey("fluidInv")) { + NBTTagCompound data = (NBTTagCompound) accessor.getNBTData().getTag("fluidInv"); + for (FluidTankInfo info : Util.FluidUtil.fluidTankInfoReadFromNBT(data)) { + if (info.fluid == null) continue; + currentToolTip + .add(Tooltip.fluidFormat(info.fluid.getLocalizedName(), info.fluid.amount, info.capacity)); + } + } + } + return currentToolTip; + } + + @Override + public NBTTagCompound getNBTData(final EntityPlayerMP player, final TileEntity te, final NBTTagCompound tag, + final World world, final int x, final int y, final int z) { + if (te instanceof TileCertusQuartzTank) { + NBTTagCompound data = new NBTTagCompound(); + Util.FluidUtil.fluidTankInfoWriteToNBT(((TileCertusQuartzTank) te).getInternalFluid(), data); + tag.setTag("fluidInv", data); + te.writeToNBT(tag); + } + return tag; + } +} diff --git a/src/main/java/com/glodblock/github/util/BlockPos.java b/src/main/java/com/glodblock/github/util/BlockPos.java index 22e268cc..fcce0e88 100644 --- a/src/main/java/com/glodblock/github/util/BlockPos.java +++ b/src/main/java/com/glodblock/github/util/BlockPos.java @@ -40,6 +40,10 @@ public class BlockPos { return new BlockPos(this.x + face.offsetX, this.y + face.offsetY, this.z + face.offsetZ, this.w); } + public BlockPos getOffSet(int x, int y, int z) { + return new BlockPos(this.x + x, this.y + y, this.z + z, this.w); + } + public TileEntity getTileEntity() { if (w != null) { return w.getTileEntity(x, y, z); diff --git a/src/main/java/com/glodblock/github/util/Util.java b/src/main/java/com/glodblock/github/util/Util.java index 66c01129..ce149abd 100644 --- a/src/main/java/com/glodblock/github/util/Util.java +++ b/src/main/java/com/glodblock/github/util/Util.java @@ -3,6 +3,8 @@ package com.glodblock.github.util; import static com.glodblock.github.common.item.ItemBaseWirelessTerminal.infinityBoosterCard; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import net.minecraft.entity.player.EntityPlayer; @@ -415,6 +417,36 @@ public final class Util { public static class FluidUtil { + public static void fluidTankInfoWriteToNBT(FluidTankInfo[] infos, NBTTagCompound data) { + int i = 0; + for (FluidTankInfo info : infos) { + if (info.fluid != null && info.fluid.amount > 0) { + NBTTagCompound fs = new NBTTagCompound(); + info.fluid.writeToNBT(fs); + fs.setInteger("capacity", info.capacity); + data.setTag("#" + i, fs); + } + i++; + } + data.setInteger("fluidInvSize", i); + } + + public static FluidTankInfo[] fluidTankInfoReadFromNBT(NBTTagCompound data) { + int i = 0; + List infos = new ArrayList<>(); + while (data.hasKey("fluidInvSize") && i < data.getInteger("fluidInvSize")) { + if (data.hasKey("#" + i)) { + NBTTagCompound tag = (NBTTagCompound) data.getTag("#" + i); + FluidStack fs = FluidStack.loadFluidStackFromNBT(tag); + infos.add(new FluidTankInfo(fs, tag.getInteger("capacity"))); + } else { + infos.add(new FluidTankInfo(null, 0)); + } + i++; + } + return infos.toArray(new FluidTankInfo[0]); + } + public static IAEFluidStack createAEFluidStack(Fluid fluid) { return createAEFluidStack(new FluidStack(fluid, FluidContainerRegistry.BUCKET_VOLUME)); }