Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

Hi, I'm trying to create a tile entity machine which can store fluids and items. I think the best way to explain what I am trying to do is to show a picture of the GUI I want to try to use.

http://puu.sh/d3f3U/ea21cb1e3f.png

At the moment, I am just focussing on getting the ability to store liquids and make the correct amount show up in the GUI. I'm wondering what classes to implement or extend in my block class.

Thanks!

 

Take a look at the

TileFluidHandler

class provided as an example by Forge.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

  • Author

Thank you for your reply. I've taken a look at the TileFluidHandler example and edited my TileEntity accordingly. From reading the documentation in IFluidHandler, I think I know what each of them do. My next question is how would I now utilize these new methods. For example, I want the left tank in the GUI to be able to hold water. How would I go about allowing water in the tank?

In your fill method, you can check if

FluidStack#fluid==FluidRegistry.WATER/tt].

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

  • Author

Ah, derp. Completely missed that. I have one more question if you don't mind. Do you know if mods that add fluid pipes such as Ender IO automatically accommodate for tile entities that implement the FluidHandler, or would I have to somehow build interaction for that myself?

Edit: Also, how would I go about changing the GUI texture to represent the amount of fluid in a tank?

For the fluid displaying in the gui, I use this code (from TE3). It is somewhat complicated, but not to hard:

public static void drawFluidTank(IFluidTank tank, int x, int y)
    {
        FluidStack fluid = tank.getFluid(); //Gets the FluidStack from the tank
        TextureManager manager = Minecraft.getMinecraft().renderEngine; //Gets the TextureManager
        if (fluid != null) //Check if the fluid is no null i.e. there is something in the tank
        {
            manager.bindTexture(manager.getResourceLocation(0)); //Bind the blocks texture map
            float amount = fluid.amount; //The amount of fluid in the tank
            float capacity = tank.getCapacity(); //The max capacity of the tank
            float scale = amount / capacity; // The 'scale' of the fluid, ranging from 0 to 1, with 0 being empty, and 1 being full
            int fluidTankHeight = 60;  // The max height of which the fluid can be drawed, i use 60, so the fluid is drawn max 60 pixels high
            int fluidAmount = (int) (scale * fluidTankHeight); // The amount of pixels the fluid has to be drawn on
            drawFluid(x, y + fluidTankHeight - fluidAmount, fluid.getFluid().getIcon(fluid), 16, fluidAmount); //Actually draw the fluid
        }
    }
    
    private static void drawFluid(int x, int y, IIcon icon, int width, int height)
    {
        int i = 0;
        int j = 0;
        
        int drawHeight = 0;
        int drawWidth = 0;
        
        for (i = 0; i < width; i += 16) // Loop through the width, with steps of 16
        {
            for (j = 0; j < height; j += 16) // Loop through the height, with steps of 16
            {
                drawWidth = Math.min(width - i, 16); // The draw width, for how much of the icon has to be drawn from
                drawHeight = Math.min(height - j, 16); // The draw height, for how much of the icon has to be drawn from
                drawRectangleFromIcon(x + i, y + j, icon, drawWidth, drawHeight); //Actually draw (part of) the icon on the gui
            }
        }
    }
    
    private static void drawRectangleFromIcon(int x, int y, IIcon icon, int width, int height)
    {
        if (icon == null) return; //Make sure the IIcon is nut null
        double minU = icon.getMinU(); //The minimun U-coordinate
        double maxU = icon.getMaxU(); //The maximum U-coordinate
        double minV = icon.getMinV(); //The minimun V-coordinate
        double maxV = icon.getMaxV(); //The maximum V-coordinate
        
        Tessellator tessellator = Tessellator.instance; //Get the Tessellator
        tessellator.startDrawingQuads(); //Start drawing a rectangle
        tessellator.addVertexWithUV(x + 0, y + height, 0, minU, minV + (maxV - minV) * height / 16.0D); // First vertex on the screen
        tessellator.addVertexWithUV(x + width, y + height, 0, minU + (maxU - minU) * width / 16.0D, minV + (maxV - minV) * height / 16.0D);// Secons vertex on the screen
        tessellator.addVertexWithUV(x + width, y + 0, 0, minU + (maxU - minU) * width / 16.0D, minV);// Third vertex on the screen
        tessellator.addVertexWithUV(x + 0, y + 0, 0, minU, minV);// Fourth vertex on the screen
        tessellator.draw(); //Draw everything on the Tessellator (the four vertices)
    }

I suggest you actually read the comments on it, or else you won't learn anything from it.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

  • Author

Thank you for your reply. I have tried to follow your instructions, however I think I have done something incorrectly. At the moment, I don't think my tile entity is accepting water.

 

This is my Block class:

 

public class BlockCoffeeMaker extends BlockACOJ implements ITileEntityProvider
{
    public BlockCoffeeMaker()
    {
        super(Material.rock);
        this.setBlockName(Names.COFFEE_MAKER);
    }

    @Override
    public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer entityPlayer, int meta, float hitX, float hitY, float hitZ)
    {
        if (world.isRemote && world.getTileEntity(x, y, z) instanceof TileEntityCoffeeMaker)
        {
            entityPlayer.openGui(ACOJ.instance, GUIs.COFFEE_MAKER.ordinal(), world, x, y, z);
        }
        return true;
    }

    @Override
    public TileEntity createNewTileEntity(World world, int meta)
    {
        return new TileEntityCoffeeMaker();
    }

    @Override
    public boolean hasTileEntity()
    {
        return true;
    }
}

 

My tileentity class:

 

public class TileEntityCoffeeMaker extends TileEntity implements IFluidHandler
{
    public static String getName()
    {
        return Names.TILE_COFFEE_MAKER;
    }

    protected FluidTank waterTank = new FluidTank(10000);

    @Override
    public void readFromNBT(NBTTagCompound tag)
    {
        super.readFromNBT(tag);
        waterTank.readFromNBT(tag);
    }

    @Override
    public void writeToNBT(NBTTagCompound tag)
    {
        super.writeToNBT(tag);
        waterTank.writeToNBT(tag);
    }

    @Override
    public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
    {
        if (resource.equals(FluidRegistry.WATER))
        {
            return waterTank.fill(resource, doFill);
        }
        return 0;
    }

    @Override
    public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
    {
        if (resource == null || !resource.isFluidEqual(waterTank.getFluid()))
        {
            return null;
        }
        return waterTank.drain(resource.amount, doDrain);
    }

    @Override
    public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
    {
        return waterTank.drain(maxDrain, doDrain);
    }

    @Override
    public boolean canFill(ForgeDirection from, Fluid fluid)
    {
        if (fluid == FluidRegistry.WATER)
        {
            return true;
        }
        return false;
    }

    @Override
    public boolean canDrain(ForgeDirection from, Fluid fluid)
    {
        return true;
    }

    @Override
    public FluidTankInfo[] getTankInfo(ForgeDirection from)
    {
        return new FluidTankInfo[] { waterTank.getInfo() };
    }
}

 

And my Gui class:

 

public class GuiCoffeeMaker extends GuiScreen
{
    private int x, y, z;
    private EntityPlayer entityPlayer;
    private World world;
    private int xSize, ySize;
    private ResourceLocation backgroundImage = new ResourceLocation(Reference.MOD_ID.toLowerCase() + ":textures/gui/GuiCoffeeMaker.png");

    public GuiCoffeeMaker(EntityPlayer entityPlayer, World world, int x, int y, int z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
        this.entityPlayer = entityPlayer;
        this.world = world;
        xSize = 176;
        ySize = 166;
    }

    @Override
    public void drawScreen(int mouseX, int mouseY, float renderPartialTicks)
    {
        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
        this.mc.getTextureManager().bindTexture(backgroundImage);
        int x = (this.width - xSize) / 2;
        int y= (this.height - ySize) /2;
        drawTexturedModalRect(x, y, 0, 0, xSize, ySize);
        fontRendererObj.drawString(StatCollector.translateToLocal("acoj.inv.coffeeMaker"), x+60, y+4, 0x313131);
        fontRendererObj.drawString(StatCollector.translateToLocal("acoj.inv.Inventory"), x+9, y+74, 0x313131);

    }

    @Override
    public boolean doesGuiPauseGame()
    {
        return false;
    }

    public static void drawFluidTank(IFluidTank tank, int x, int y)
    {
        FluidStack fluid = tank.getFluid();
        TextureManager manager = Minecraft.getMinecraft().renderEngine;
        if (fluid != null)
        {
            manager.bindTexture(manager.getResourceLocation(0));
            float amount = fluid.amount;
            float capacity = tank.getCapacity();
            float scale = amount / capacity;
            int fluidTankHeight = 60;
            int fluidAmount = (int) (scale * fluidTankHeight);
            drawFluid(x, y + fluidTankHeight - fluidAmount, fluid.getFluid().getIcon(fluid), 16, fluidAmount);
        }
    }

    private static void drawFluid(int x, int y, IIcon icon, int width, int height)
    {
        int i = 0;
        int j = 0;

        int drawHeight = 0;
        int drawWidth = 0;

        for (i = 0; i < width; i += 16)
        {
            for (j = 0; j < height; j += 16)
            {
                drawWidth = Math.min(width - i, 16);
                drawHeight = Math.min(height - j, 16);
                drawRectangleFromIcon(x + i, y+ j, icon, drawWidth, drawHeight);
            }
        }
    }

    private static void drawRectangleFromIcon(int x, int y, IIcon icon, int width, int height)
    {
        if (icon == null) return;
        double minU = icon.getMinU();
        double maxU = icon.getMaxU();
        double minV = icon.getMinV();
        double maxV = icon.getMaxV();

        Tessellator tessellator = Tessellator.instance;
        tessellator.startDrawingQuads();
        tessellator.addVertexWithUV(x + 0, y + height, 0, minU, minV + (maxV - minV) * height / 16.0D);
        tessellator.addVertexWithUV(x + width, y + height, 0, minU + (maxU - minU) * width / 16.0D, minV + (maxV - minV) * height / 16.0D);
        tessellator.addVertexWithUV(x + width, y + 0, 0, minU + (maxU - minU) * width / 16.0D, minV);
        tessellator.addVertexWithUV(x + 0, y + 0, 0, minU, minV);
        tessellator.draw();
    }
}

 

If I am missing any relevant code, please tell me. I know for sure that I have made a mistake or do not understand something. If you could please point out what I may have done wrong, please tell me.

Thanks! :D

  • Author

Wow, I knew it would be a silly mistake like that. Thank you so much.

Edit: If I were to want to manually add fluids to the tank, would I directly access the tank in the TileEntity class?

  • Author

Oh, sorry, I definitely should've tried a bit harder before posting. I bet that kind of thing annoys the mods on here a bit. Thank you so much for your help, I finally have it working.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

Important Information

By using this site, you agree to our Terms of Use.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.