Jump to content

[Solved][1.7.10]Machine which can hold fluids


grand_mind1

Recommended Posts

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!

 

Link to comment
Share on other sites

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/

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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/

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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/

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

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