buildcraftAdditions.compat.nei.RecipeHandlerBase.java Source code

Java tutorial

Introduction

Here is the source code for buildcraftAdditions.compat.nei.RecipeHandlerBase.java

Source

package buildcraftAdditions.compat.nei;

import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;

import org.lwjgl.opengl.GL11;

import net.minecraft.block.Block;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IIcon;

import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTank;
import net.minecraftforge.fluids.IFluidBlock;
import net.minecraftforge.fluids.IFluidContainerItem;

import buildcraftAdditions.utils.RenderUtils;

import codechicken.lib.gui.GuiDraw;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.PositionedStack;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.recipe.GuiCraftingRecipe;
import codechicken.nei.recipe.GuiRecipe;
import codechicken.nei.recipe.GuiUsageRecipe;
import codechicken.nei.recipe.ICraftingHandler;
import codechicken.nei.recipe.IUsageHandler;
import codechicken.nei.recipe.TemplateRecipeHandler;

/**
 * Copyright (c) 2014-2015, AEnterprise
 * http://buildcraftadditions.wordpress.com/
 * Buildcraft Additions is distributed under the terms of GNU GPL v3.0
 * Please check the contents of the license located in
 * http://buildcraftadditions.wordpress.com/wiki/licensing-stuff/
 */
public abstract class RecipeHandlerBase extends TemplateRecipeHandler implements ICraftingHandler, IUsageHandler {

    public abstract String getRecipeID();

    public String getRecipeSubName() {
        return null;
    }

    public void changeToGuiTexture() {
        GuiDraw.changeTexture(this.getGuiTexture());
        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    }

    public void addTransferRect(int x, int y, int width, int height) {
        this.transferRects.add(new RecipeTransferRect(new Rectangle(x, y, width, height), this.getRecipeID()));
    }

    @Override
    public void drawForeground(int recipe) {
        super.drawForeground(recipe);
        this.drawFluidTanks(recipe);
        if (recipe % this.recipiesPerPage() == 0 && this.getRecipeSubName() != null) {
            GuiDraw.drawStringC(this.getRecipeSubName(), 83, -2, 0x404040, false);
        }
        this.changeToGuiTexture();
    }

    @Override
    public void loadCraftingRecipes(String outputId, Object... results) {
        if (outputId.equals("liquid"))
            this.loadCraftingRecipes((FluidStack) results[0]);
        else if (outputId.equals(this.getRecipeID()))
            this.loadAllRecipes();
        else
            super.loadCraftingRecipes(outputId, results);
    }

    public void loadAllRecipes() {

    }

    @Override
    public void loadCraftingRecipes(ItemStack result) {
        FluidStack fluid = getFluidStackFromItemStack(result);
        if (fluid != null)
            this.loadCraftingRecipes(fluid);
    }

    public void loadCraftingRecipes(FluidStack result) {

    }

    @Override
    public void loadUsageRecipes(String inputId, Object... ingredients) {
        if (inputId.equals("liquid"))
            this.loadUsageRecipes((FluidStack) ingredients[0]);
        else
            super.loadUsageRecipes(inputId, ingredients);
    }

    @Override
    public void loadUsageRecipes(ItemStack ingred) {
        FluidStack fluid = getFluidStackFromItemStack(ingred);
        if (fluid != null)
            this.loadUsageRecipes(fluid);
    }

    public void loadUsageRecipes(FluidStack ingredient) {

    }

    protected boolean transferFluidTank(GuiRecipe guiRecipe, int recipe, boolean usage) {
        CachedBaseRecipe crecipe = (CachedBaseRecipe) this.arecipes.get(recipe);
        Point mousepos = GuiDraw.getMousePosition();
        Point offset = guiRecipe.getRecipePosition(recipe);
        Point relMouse = new Point(mousepos.x - (guiRecipe.width - 176) / 2 - offset.x,
                mousepos.y - (guiRecipe.height - 166) / 2 - offset.y);

        if (crecipe.getFluidTanks() != null) {
            for (PositionedFluidTank tank : crecipe.getFluidTanks()) {
                if (tank.position.contains(relMouse))
                    return tank.transfer(usage);
            }
        }

        return false;
    }

    public void drawFluidTanks(int recipe) {
        CachedBaseRecipe crecipe = (CachedBaseRecipe) this.arecipes.get(recipe);
        if (crecipe.getFluidTanks() != null) {
            crecipe.drawUpdate();
            for (PositionedFluidTank fluidTank : crecipe.getFluidTanks())
                fluidTank.draw();
        }
    }

    @Override
    public List<String> handleTooltip(GuiRecipe guiRecipe, List<String> currenttip, int recipe) {
        super.handleTooltip(guiRecipe, currenttip, recipe);
        CachedBaseRecipe crecipe = (CachedBaseRecipe) this.arecipes.get(recipe);
        if (GuiContainerManager.shouldShowTooltip(guiRecipe)) {
            Point mouse = GuiDraw.getMousePosition();
            Point offset = guiRecipe.getRecipePosition(recipe);
            Point relMouse = new Point(mouse.x - (guiRecipe.width - 176) / 2 - offset.x,
                    mouse.y - (guiRecipe.height - 166) / 2 - offset.y);

            currenttip = this.provideTooltip(guiRecipe, currenttip, crecipe, relMouse);
        }
        return currenttip;
    }

    @Override
    public List<String> handleItemTooltip(GuiRecipe guiRecipe, ItemStack itemStack, List<String> currenttip,
            int recipe) {
        super.handleItemTooltip(guiRecipe, itemStack, currenttip, recipe);
        CachedBaseRecipe crecipe = (CachedBaseRecipe) this.arecipes.get(recipe);
        Point mouse = GuiDraw.getMousePosition();
        Point offset = guiRecipe.getRecipePosition(recipe);
        Point relMouse = new Point(mouse.x - (guiRecipe.width - 176) / 2 - offset.x,
                mouse.y - (guiRecipe.height - 166) / 2 - offset.y);

        currenttip = this.provideItemTooltip(guiRecipe, itemStack, currenttip, crecipe, relMouse);
        return currenttip;
    }

    public List<String> provideTooltip(GuiRecipe guiRecipe, List<String> currenttip, CachedBaseRecipe crecipe,
            Point relMouse) {
        if (crecipe.getFluidTanks() != null) {
            for (PositionedFluidTank tank : crecipe.getFluidTanks()) {
                if (tank.position.contains(relMouse)) {
                    tank.handleTooltip(currenttip);
                }
            }
        }
        return currenttip;
    }

    public List<String> provideItemTooltip(GuiRecipe guiRecipe, ItemStack itemStack, List<String> currenttip,
            CachedBaseRecipe crecipe, Point relMouse) {
        for (PositionedStack stack : crecipe.getIngredients()) {
            if (stack instanceof PositionedStackAdv && ((PositionedStackAdv) stack).getRect().contains(relMouse))
                currenttip = ((PositionedStackAdv) stack).handleTooltip(guiRecipe, currenttip);
        }
        for (PositionedStack stack : crecipe.getOtherStacks()) {
            if (stack instanceof PositionedStackAdv && ((PositionedStackAdv) stack).getRect().contains(relMouse))
                currenttip = ((PositionedStackAdv) stack).handleTooltip(guiRecipe, currenttip);
        }
        PositionedStack stack = crecipe.getResult();
        if (stack instanceof PositionedStackAdv && ((PositionedStackAdv) stack).getRect().contains(relMouse))
            currenttip = ((PositionedStackAdv) stack).handleTooltip(guiRecipe, currenttip);
        return currenttip;
    }

    @Override
    public boolean keyTyped(GuiRecipe gui, char keyChar, int keyCode, int recipe) {
        if (keyCode == NEIClientConfig.getKeyBinding("gui.recipe")) {
            if (this.transferFluidTank(gui, recipe, false))
                return true;
        } else if (keyCode == NEIClientConfig.getKeyBinding("gui.usage")) {
            if (this.transferFluidTank(gui, recipe, true))
                return true;
        }
        return super.keyTyped(gui, keyChar, keyCode, recipe);
    }

    @Override
    public boolean mouseClicked(GuiRecipe gui, int button, int recipe) {
        if (button == 0) {
            if (this.transferFluidTank(gui, recipe, false))
                return true;
        } else if (button == 1) {
            if (this.transferFluidTank(gui, recipe, true))
                return true;
        }
        return super.mouseClicked(gui, button, recipe);
    }

    public static FluidStack getFluidStackFromItemStack(ItemStack stack) {
        if (stack != null) {
            if (stack.getItem() instanceof IFluidContainerItem) {
                IFluidContainerItem ctr = (IFluidContainerItem) stack.getItem();
                return ctr.getFluid(stack);
            } else if (FluidContainerRegistry.isFilledContainer(stack))
                return FluidContainerRegistry.getFluidForFilledItem(stack);
            else if (stack.getItem() instanceof ItemBlock) {
                Block b = Block.getBlockFromItem(stack.getItem());
                if (b != null && b instanceof IFluidBlock && ((IFluidBlock) b).getFluid() != null)
                    return new FluidStack(((IFluidBlock) b).getFluid(), 1000);
            }
        }
        return null;
    }

    public abstract class CachedBaseRecipe extends CachedRecipe {

        public List<PositionedFluidTank> getFluidTanks() {
            List<PositionedFluidTank> tanks = new ArrayList<PositionedFluidTank>();
            PositionedFluidTank tank = this.getFluidTank();
            if (tank != null)
                tanks.add(tank);
            return tanks;
        }

        public PositionedFluidTank getFluidTank() {
            return null;
        }

        public void drawUpdate() {

        }
    }

    public class PositionedStackAdv extends PositionedStack {

        private List<String> tooltip = new ArrayList<String>();

        public PositionedStackAdv(Object object, int x, int y) {
            super(object, x, y);
        }

        public PositionedStackAdv(Object object, int x, int y, List<String> tooltip) {
            super(object, x, y);
            this.addToTooltip(tooltip);
        }

        public Rectangle getRect() {
            return new Rectangle(this.relx - 1, this.rely - 1, 18, 18);
        }

        public List<String> handleTooltip(GuiRecipe guiRecipe, List<String> currenttip) {
            if (!this.tooltip.isEmpty()) {
                for (String tip : this.tooltip)
                    currenttip.add(tip);
            }
            return currenttip;
        }

        public PositionedStackAdv addToTooltip(List<String> lines) {
            for (String tip : lines)
                this.tooltip.add(tip);
            return this;
        }

        public PositionedStackAdv addToTooltip(String line) {
            this.tooltip.add(line);
            return this;
        }
    }

    public class PositionedFluidTank {

        public FluidTank tank;
        public Rectangle position;
        public String overlayTexture;
        public Point overlayTexturePos;
        public boolean flowingTexture = false;
        public boolean showAmount = false;
        public boolean perTick = false;

        public PositionedFluidTank(FluidTank tank, Rectangle position, String overlayTexture,
                Point overlayTexturePos) {
            this.position = position;
            this.tank = tank;
            this.overlayTexture = overlayTexture;
            this.overlayTexturePos = overlayTexturePos;
        }

        public PositionedFluidTank(FluidTank tank, Rectangle position) {
            this(tank, position, null, null);
        }

        public PositionedFluidTank(FluidStack fluid, int capacity, Rectangle position, String overlayTexture,
                Point overlayTexturePos) {
            this(new FluidTank(fluid != null ? fluid.copy() : null, capacity), position, overlayTexture,
                    overlayTexturePos);
        }

        public PositionedFluidTank(FluidStack fluid, int capacity, Rectangle position) {
            this(fluid, capacity, position, null, null);
        }

        public PositionedFluidTank setUseFlowingTexture(boolean useFlowingTexture) {
            this.flowingTexture = useFlowingTexture;
            return this;
        }

        public PositionedFluidTank setShowAmount(boolean showAmount) {
            this.showAmount = showAmount;
            return this;
        }

        public PositionedFluidTank setPerTick(boolean perTick) {
            this.perTick = perTick;
            return this;
        }

        public List<String> handleTooltip(List<String> currenttip) {
            if (this.tank == null || this.tank.getFluid() == null || this.tank.getFluid().getFluid() == null
                    || this.tank.getFluid().amount <= 0)
                return currenttip;
            currenttip.add(this.tank.getFluid().getLocalizedName());
            if (this.showAmount)
                currenttip.add(EnumChatFormatting.GRAY.toString() + this.tank.getFluid().amount
                        + (this.perTick ? " mB/t" : " mB"));
            return currenttip;
        }

        public boolean transfer(boolean usage) {
            if (this.tank.getFluid() != null && this.tank.getFluid().amount > 0) {
                if (usage) {
                    if (!GuiUsageRecipe.openRecipeGui("liquid", new Object[] { this.tank.getFluid() }))
                        return false;
                } else {
                    if (!GuiCraftingRecipe.openRecipeGui("liquid", new Object[] { this.tank.getFluid() }))
                        return false;
                }
                return true;
            }
            return false;
        }

        public void draw() {
            if (this.tank == null || this.tank.getFluid() == null || this.tank.getFluid().getFluid() == null
                    || this.tank.getFluid().amount <= 0)
                return;
            IIcon fluidIcon = null;
            if (this.flowingTexture && this.tank.getFluid().getFluid().getFlowingIcon() != null)
                fluidIcon = this.tank.getFluid().getFluid().getFlowingIcon();
            else if (this.tank.getFluid().getFluid().getStillIcon() != null)
                fluidIcon = this.tank.getFluid().getFluid().getStillIcon();
            else
                return;

            GuiDraw.changeTexture(RenderUtils.MC_BLOCK_SHEET);
            int color = this.tank.getFluid().getFluid().getColor(this.tank.getFluid());
            GL11.glColor3ub((byte) (color >> 16 & 0xFF), (byte) (color >> 8 & 0xFF), (byte) (color & 0xFF));
            GL11.glDisable(GL11.GL_BLEND);

            int amount = Math.max(Math.min(this.position.height,
                    this.tank.getFluid().amount * this.position.height / this.tank.getCapacity()), 1);
            int posY = this.position.y + this.position.height - amount;

            for (int i = 0; i < this.position.width; i += 16) {
                for (int j = 0; j < amount; j += 16) {
                    int drawWidth = Math.min(this.position.width - i, 16);
                    int drawHeight = Math.min(amount - j, 16);

                    int drawX = this.position.x + i;
                    int drawY = posY + j;

                    double minU = fluidIcon.getMinU();
                    double maxU = fluidIcon.getMaxU();
                    double minV = fluidIcon.getMinV();
                    double maxV = fluidIcon.getMaxV();

                    Tessellator tessellator = Tessellator.instance;
                    tessellator.startDrawingQuads();
                    tessellator.addVertexWithUV(drawX, drawY + drawHeight, 0, minU,
                            minV + (maxV - minV) * drawHeight / 16F);
                    tessellator.addVertexWithUV(drawX + drawWidth, drawY + drawHeight, 0,
                            minU + (maxU - minU) * drawWidth / 16F, minV + (maxV - minV) * drawHeight / 16F);
                    tessellator.addVertexWithUV(drawX + drawWidth, drawY, 0, minU + (maxU - minU) * drawWidth / 16F,
                            minV);
                    tessellator.addVertexWithUV(drawX, drawY, 0, minU, minV);
                    tessellator.draw();
                }
            }

            GL11.glEnable(GL11.GL_BLEND);

            if (this.overlayTexture != null && this.overlayTexturePos != null) {
                GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
                GuiDraw.changeTexture(this.overlayTexture);
                GuiDraw.drawTexturedModalRect(this.position.x, this.position.y, this.overlayTexturePos.x,
                        this.overlayTexturePos.y, this.position.width, this.position.height);
            }
        }

    }
}