Package pneumaticCraft.common.tileentity

Source Code of pneumaticCraft.common.tileentity.TileEntityProgrammer

package pneumaticCraft.common.tileentity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.ChunkPosition;
import pneumaticCraft.api.item.IProgrammable;
import pneumaticCraft.client.AreaShowHandler;
import pneumaticCraft.client.AreaShowManager;
import pneumaticCraft.common.NBTUtil;
import pneumaticCraft.common.block.Blockss;
import pneumaticCraft.common.item.ItemProgrammingPuzzle;
import pneumaticCraft.common.progwidgets.IAreaProvider;
import pneumaticCraft.common.progwidgets.IProgWidget;
import pneumaticCraft.common.progwidgets.ProgWidgetArea;
import pneumaticCraft.common.progwidgets.ProgWidgetDig;
import pneumaticCraft.common.progwidgets.ProgWidgetEntityAttack;
import pneumaticCraft.common.progwidgets.ProgWidgetGoToLocation;
import pneumaticCraft.common.progwidgets.ProgWidgetInventoryExport;
import pneumaticCraft.common.progwidgets.ProgWidgetInventoryImport;
import pneumaticCraft.common.progwidgets.ProgWidgetItemFilter;
import pneumaticCraft.common.progwidgets.ProgWidgetPickupItem;
import pneumaticCraft.common.progwidgets.ProgWidgetPlace;
import pneumaticCraft.common.progwidgets.ProgWidgetStart;
import pneumaticCraft.common.progwidgets.ProgWidgetString;
import pneumaticCraft.common.util.PneumaticCraftUtils;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

public class TileEntityProgrammer extends TileEntityBase implements IInventory{
    public List<IProgWidget> progWidgets = new ArrayList<IProgWidget>();
    public static List<IProgWidget> registeredWidgets = new ArrayList<IProgWidget>();
    @SideOnly(Side.CLIENT)
    private static AreaShowHandler previewedArea;
    public int redstoneMode;
    private ItemStack[] inventory = new ItemStack[1];

    public static final int PROGRAM_SLOT = 0;

    static {
        registeredWidgets.add(new ProgWidgetStart());
        registeredWidgets.add(new ProgWidgetArea());
        registeredWidgets.add(new ProgWidgetString());
        registeredWidgets.add(new ProgWidgetItemFilter());
        registeredWidgets.add(new ProgWidgetEntityAttack());
        registeredWidgets.add(new ProgWidgetDig());
        registeredWidgets.add(new ProgWidgetPlace());
        registeredWidgets.add(new ProgWidgetPickupItem());
        registeredWidgets.add(new ProgWidgetInventoryExport());
        registeredWidgets.add(new ProgWidgetInventoryImport());
        registeredWidgets.add(new ProgWidgetGoToLocation());
    }

    @Override
    public void readFromNBT(NBTTagCompound tag){
        super.readFromNBT(tag);
        redstoneMode = tag.getInteger("redstoneMode");

        // Read in the ItemStacks in the inventory from NBT
        NBTTagList tagList = tag.getTagList("Items", 10);
        inventory = new ItemStack[getSizeInventory()];
        for(int i = 0; i < tagList.tagCount(); ++i) {
            NBTTagCompound tagCompound = tagList.getCompoundTagAt(i);
            byte slot = tagCompound.getByte("Slot");
            if(slot >= 0 && slot < inventory.length) {
                inventory[slot] = ItemStack.loadItemStackFromNBT(tagCompound);
            }
        }

        readProgWidgetsFromNBT(tag);
    }

    @Override
    public void writeToNBT(NBTTagCompound tag){
        super.writeToNBT(tag);
        tag.setInteger("redstoneMode", redstoneMode);

        // Write the ItemStacks in the inventory to NBT
        NBTTagList tagList = new NBTTagList();
        for(int currentIndex = 0; currentIndex < inventory.length; ++currentIndex) {
            if(inventory[currentIndex] != null) {
                NBTTagCompound tagCompound = new NBTTagCompound();
                tagCompound.setByte("Slot", (byte)currentIndex);
                inventory[currentIndex].writeToNBT(tagCompound);
                tagList.appendTag(tagCompound);
            }
        }
        tag.setTag("Items", tagList);

        writeProgWidgetsToNBT(tag);
    }

    public void readProgWidgetsFromNBT(NBTTagCompound tag){
        progWidgets = getWidgetsFromNBT(tag);
    }

    public void writeProgWidgetsToNBT(NBTTagCompound tag){
        setWidgetsToNBT(progWidgets, tag);
    }

    public static List<IProgWidget> getWidgetsFromNBT(NBTTagCompound tag){
        List<IProgWidget> progWidgets = new ArrayList<IProgWidget>();
        NBTTagList widgetTags = tag.getTagList("widgets", 10);
        for(int i = 0; i < widgetTags.tagCount(); i++) {
            NBTTagCompound widgetTag = widgetTags.getCompoundTagAt(i);
            String widgetName = widgetTag.getString("name");
            for(IProgWidget widget : registeredWidgets) {
                if(widgetName.equals(widget.getWidgetString()) || widgetName.equals(widget.getLegacyString())) {//create the right progWidget for the given id tag.
                    IProgWidget addedWidget = widget.copy();
                    addedWidget.readFromNBT(widgetTag);
                    progWidgets.add(addedWidget);
                    break;
                }
            }
        }
        updatePuzzleConnections(progWidgets);
        return progWidgets;
    }

    public static void setWidgetsToNBT(List<IProgWidget> widgets, NBTTagCompound tag){
        NBTTagList widgetTags = new NBTTagList();
        for(IProgWidget widget : widgets) {
            NBTTagCompound widgetTag = new NBTTagCompound();
            widget.writeToNBT(widgetTag);
            widgetTags.appendTag(widgetTag);
        }
        tag.setTag("widgets", widgetTags);
    }

    public static void updatePuzzleConnections(List<IProgWidget> progWidgets){
        for(IProgWidget widget : progWidgets) {
            widget.setParent(null);
            Class<? extends IProgWidget>[] parameters = widget.getParameters();
            if(parameters != null) {
                for(int i = 0; i < parameters.length * 2; i++) {
                    widget.setParameter(i, null);
                }
            }
            if(widget.hasStepOutput()) widget.setOutputWidget(null);
        }
        for(IProgWidget checkedWidget : progWidgets) {
            //check for connection to the right of the checked widget.
            Class<? extends IProgWidget>[] parameters = checkedWidget.getParameters();
            if(parameters != null) {
                for(IProgWidget widget : progWidgets) {
                    if(widget != checkedWidget && checkedWidget.getX() + checkedWidget.getWidth() / 2 == widget.getX()) {
                        for(int i = 0; i < parameters.length; i++) {
                            if(parameters[i] == widget.returnType() && checkedWidget.getY() + i * 11 == widget.getY()) {
                                checkedWidget.setParameter(i, widget);
                                widget.setParent(checkedWidget);
                            }
                        }
                    }
                }
            }

            //check for connection to the bottom of the checked widget.
            if(checkedWidget.hasStepOutput()) {
                for(IProgWidget widget : progWidgets) {
                    if(widget.hasStepInput() && widget.getX() == checkedWidget.getX() && widget.getY() == checkedWidget.getY() + checkedWidget.getHeight() / 2) {
                        checkedWidget.setOutputWidget(widget);
                    }
                }
            }
        }

        //go again for the blacklist (as those are mirrored)
        for(IProgWidget checkedWidget : progWidgets) {
            if(checkedWidget.returnType() == null) { //if it's a program (import/export inventory, attack entity) rather than a parameter (area, item filter).
                Class<? extends IProgWidget>[] parameters = checkedWidget.getParameters();
                if(parameters != null) {
                    for(int i = 0; i < parameters.length; i++) {
                        for(IProgWidget widget : progWidgets) {
                            if(parameters[i] == widget.returnType()) {
                                if(widget != checkedWidget && widget.getX() + widget.getWidth() / 2 == checkedWidget.getX() && widget.getY() == checkedWidget.getY() + i * 11) {
                                    IProgWidget root = widget;
                                    while(root.getParent() != null) {
                                        root = root.getParent();
                                    }
                                    checkedWidget.setParameter(i + parameters.length, root);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    @Override
    public void handleGUIButtonPress(int buttonID, EntityPlayer player){
        switch(buttonID){
            case 0:
                if(redstoneMode++ > 1) redstoneMode = 1;
                break;
            case 1:
                NBTTagCompound tag = inventory[PROGRAM_SLOT] != null ? inventory[PROGRAM_SLOT].getTagCompound() : null;
                if(tag != null) readProgWidgetsFromNBT(tag);
                else progWidgets = new ArrayList<IProgWidget>();
                break;
            case 2:
                if(inventory[PROGRAM_SLOT] != null) {
                    if(!player.capabilities.isCreativeMode) {
                        List<ItemStack> requiredStacks = getRequiredPuzzleStacks();
                        for(ItemStack stack : requiredStacks) {
                            if(!hasEnoughPuzzleStacks(player, stack)) return;
                        }
                        for(ItemStack stack : requiredStacks) {
                            int left = stack.stackSize;
                            for(int i = 0; i < player.inventory.getSizeInventory(); i++) {
                                if(PneumaticCraftUtils.areStacksEqual(stack, player.inventory.getStackInSlot(i), true, true, false, false)) {
                                    left -= player.inventory.decrStackSize(i, left).stackSize;
                                    if(left <= 0) break;
                                }
                            }
                        }
                        List<ItemStack> returnedStacks = getReturnedPuzzleStacks();
                        for(ItemStack stack : returnedStacks) {
                            if(!player.inventory.addItemStackToInventory(stack)) {
                                player.dropPlayerItemWithRandomChoice(stack.copy(), false);
                            }
                        }
                    }
                    tag = inventory[PROGRAM_SLOT].getTagCompound();
                    if(tag == null) {
                        tag = new NBTTagCompound();
                        inventory[PROGRAM_SLOT].setTagCompound(tag);
                    }
                    writeProgWidgetsToNBT(tag);
                }
                break;
        }
        sendDescriptionPacket();
    }

    public List<ItemStack> getRequiredPuzzleStacks(){
        List<ItemStack> stacks = new ArrayList<ItemStack>();
        if(((IProgrammable)inventory[PROGRAM_SLOT].getItem()).usesPieces(inventory[PROGRAM_SLOT])) {
            Map<String, Integer> tePieces = getPuzzleSummary(progWidgets);
            Map<String, Integer> dronePieces = getPuzzleSummary(getProgWidgets(inventory[PROGRAM_SLOT]));
            for(String includedWidget : tePieces.keySet()) {
                Integer existingWidgets = dronePieces.get(includedWidget);
                if(existingWidgets != null) {
                    Integer neededWidgets = tePieces.get(includedWidget);
                    if(neededWidgets > existingWidgets) {
                        ItemStack stack = ItemProgrammingPuzzle.getStackForWidgetKey(includedWidget);
                        stack.stackSize = (neededWidgets - existingWidgets) * inventory[PROGRAM_SLOT].stackSize;
                        stacks.add(stack);
                    }
                } else {
                    ItemStack stack = ItemProgrammingPuzzle.getStackForWidgetKey(includedWidget);
                    stack.stackSize = tePieces.get(includedWidget) * inventory[PROGRAM_SLOT].stackSize;
                    stacks.add(stack);
                }
            }
        }
        return stacks;
    }

    public List<ItemStack> getReturnedPuzzleStacks(){
        List<ItemStack> stacks = new ArrayList<ItemStack>();
        if(((IProgrammable)inventory[PROGRAM_SLOT].getItem()).usesPieces(inventory[PROGRAM_SLOT])) {
            Map<String, Integer> tePieces = getPuzzleSummary(progWidgets);
            Map<String, Integer> dronePieces = getPuzzleSummary(getProgWidgets(inventory[PROGRAM_SLOT]));

            for(String availableWidget : dronePieces.keySet()) {
                Integer requiredWidget = tePieces.get(availableWidget);
                if(requiredWidget != null) {
                    Integer availableWidgets = dronePieces.get(availableWidget);
                    if(availableWidgets > requiredWidget) {
                        ItemStack stack = ItemProgrammingPuzzle.getStackForWidgetKey(availableWidget);
                        stack.stackSize = (availableWidgets - requiredWidget) * inventory[PROGRAM_SLOT].stackSize;
                        while(stack.stackSize > stack.getMaxStackSize()) {
                            stacks.add(stack.splitStack(stack.getMaxStackSize()));
                        }
                        stacks.add(stack);
                    }
                } else {
                    ItemStack stack = ItemProgrammingPuzzle.getStackForWidgetKey(availableWidget);
                    stack.stackSize = dronePieces.get(availableWidget) * inventory[PROGRAM_SLOT].stackSize;
                    while(stack.stackSize > stack.getMaxStackSize()) {
                        stacks.add(stack.splitStack(stack.getMaxStackSize()));
                    }
                    stacks.add(stack);
                }
            }
        }
        return stacks;
    }

    public static List<IProgWidget> getProgWidgets(ItemStack iStack){
        if(NBTUtil.hasTag(iStack, "widgets")) {
            return TileEntityProgrammer.getWidgetsFromNBT(iStack.getTagCompound());
        } else {
            return new ArrayList<IProgWidget>();
        }
    }

    public boolean hasEnoughPuzzleStacks(EntityPlayer player, ItemStack stack){
        int amountLeft = stack.stackSize;
        for(int i = 0; i < player.inventory.getSizeInventory(); i++) {
            ItemStack playerStack = player.inventory.getStackInSlot(i);
            if(PneumaticCraftUtils.areStacksEqual(playerStack, stack, true, true, false, false)) {
                amountLeft -= playerStack.stackSize;
                if(amountLeft <= 0) return true;
            }
        }
        return false;
    }

    public static Map<String, Integer> getPuzzleSummary(List<IProgWidget> widgets){
        Map<String, Integer> map = new HashMap<String, Integer>();
        for(IProgWidget widget : widgets) {
            if(!map.containsKey(widget.getWidgetString())) {
                map.put(widget.getWidgetString(), 1);
            } else {
                map.put(widget.getWidgetString(), map.get(widget.getWidgetString()) + 1);
            }
        }
        return map;
    }

    // INVENTORY METHODS

    /**
     * Returns the number of slots in the inventory.
     */
    @Override
    public int getSizeInventory(){
        return inventory.length;
    }

    /**
     * Returns the stack in slot i
     */
    @Override
    public ItemStack getStackInSlot(int slot){
        return inventory[slot];
    }

    @Override
    public ItemStack decrStackSize(int slot, int amount){
        ItemStack itemStack = getStackInSlot(slot);
        if(itemStack != null) {
            if(itemStack.stackSize <= amount) {
                setInventorySlotContents(slot, null);
            } else {
                itemStack = itemStack.splitStack(amount);
                if(itemStack.stackSize == 0) {
                    setInventorySlotContents(slot, null);
                }
            }
        }

        return itemStack;
    }

    @Override
    public ItemStack getStackInSlotOnClosing(int slot){
        ItemStack itemStack = getStackInSlot(slot);
        if(itemStack != null) {
            setInventorySlotContents(slot, null);
        }
        return itemStack;
    }

    @Override
    public void setInventorySlotContents(int slot, ItemStack itemStack){
        inventory[slot] = itemStack;
        if(itemStack != null && itemStack.stackSize > getInventoryStackLimit()) {
            itemStack.stackSize = getInventoryStackLimit();
        }
    }

    @Override
    public String getInventoryName(){
        return Blockss.programmer.getUnlocalizedName();
    }

    @Override
    public int getInventoryStackLimit(){

        return 64;
    }

    @Override
    public boolean isItemValidForSlot(int i, ItemStack itemstack){
        if(i == PROGRAM_SLOT && itemstack != null && (!(itemstack.getItem() instanceof IProgrammable) || !((IProgrammable)itemstack.getItem()).canProgram(itemstack))) return false;
        return true;
    }

    @Override
    public void updateEntity(){
        super.updateEntity();
    }

    public boolean previewArea(int widgetX, int widgetY){
        for(IProgWidget w : progWidgets) {
            if(w.getX() == widgetX && w.getY() == widgetY && w instanceof IAreaProvider) {
                AreaShowManager.getInstance().removeHandler(previewedArea);
                Set<ChunkPosition> area = ((IAreaProvider)w).getArea();
                if(area.size() > 10000) return false;
                previewedArea = AreaShowManager.getInstance().showArea(area, 0x00FF00);
            }
        }
        return true;
    }

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

    @Override
    public boolean isUseableByPlayer(EntityPlayer var1){
        return isGuiUseableByPlayer(var1);
    }

    @Override
    public void openInventory(){}

    @Override
    public void closeInventory(){}
}
TOP

Related Classes of pneumaticCraft.common.tileentity.TileEntityProgrammer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.