Package invtweaks

Source Code of invtweaks.InvTweaksHandlerSorting

package invtweaks;

import invtweaks.InvTweaksConst;
import invtweaks.InvTweaksItemTree;
import invtweaks.InvTweaksItemTreeItem;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;


import net.minecraft.client.Minecraft;
import net.minecraft.src.InvTweaksObfuscation;
import net.minecraft.src.Item;
import net.minecraft.src.ItemArmor;
import net.minecraft.src.ItemStack;
import net.minecraft.src.Slot;

/**
* Core of the sorting behaviour. Allows to move items in a container
* (inventory or chest) with respect to the mod's configuration.
*
* @author Jimeo Wan
*
*/
public class InvTweaksHandlerSorting extends InvTweaksObfuscation {

    private static final Logger log = Logger.getLogger("InvTweaks");

    public static final boolean STACK_NOT_EMPTIED = true;
    public static final boolean STACK_EMPTIED = false;

    private static int[] DEFAULT_LOCK_PRIORITIES = null;
    private static boolean[] DEFAULT_FROZEN_SLOTS = null;
    private static final int MAX_CONTAINER_SIZE = 999;

    public static final int ALGORITHM_DEFAULT = 0;
    public static final int ALGORITHM_VERTICAL = 1;
    public static final int ALGORITHM_HORIZONTAL = 2;
    public static final int ALGORITHM_INVENTORY = 3;
    public static final int ALGORITHM_EVEN_STACKS = 4;

    private InvTweaksContainerSectionManager containerMgr;
    private int algorithm;
    private int size;
    private boolean sortArmorParts;

    private InvTweaksItemTree tree;
    private Vector<InvTweaksConfigSortingRule> rules;
    private int[] rulePriority;
    private int[] keywordOrder;
    private int[] lockPriorities;
    private boolean[] frozenSlots;

    public InvTweaksHandlerSorting(Minecraft mc, InvTweaksConfig config,
            InvTweaksContainerSection section, int algorithm, int rowSize) throws Exception {
        super(mc);

        // Init constants

        if (DEFAULT_LOCK_PRIORITIES == null) {
            DEFAULT_LOCK_PRIORITIES = new int[MAX_CONTAINER_SIZE];
            for (int i = 0; i < MAX_CONTAINER_SIZE; i++) {
                DEFAULT_LOCK_PRIORITIES[i] = 0;
            }
        }
        if (DEFAULT_FROZEN_SLOTS == null) {
            DEFAULT_FROZEN_SLOTS = new boolean[MAX_CONTAINER_SIZE];
            for (int i = 0; i < MAX_CONTAINER_SIZE; i++) {
                DEFAULT_FROZEN_SLOTS[i] = false;
            }
        }

        // Init attributes

        this.containerMgr = new InvTweaksContainerSectionManager(mc, section);
        this.size = containerMgr.getSize();
        this.sortArmorParts = config.getProperty(InvTweaksConfig.PROP_ENABLE_AUTO_EQUIP_ARMOR).equals(InvTweaksConfig.VALUE_TRUE)
                && !isGuiInventoryCreative(getCurrentScreen()); // FIXME Armor parts disappear when sorting in creative mode while holding an item

        this.rules = config.getRules();
        this.tree = config.getTree();
        if (section == InvTweaksContainerSection.INVENTORY) {
            this.lockPriorities = config.getLockPriorities();
            this.frozenSlots = config.getFrozenSlots();
            this.algorithm = ALGORITHM_INVENTORY;
        } else {
            this.lockPriorities = DEFAULT_LOCK_PRIORITIES;
            this.frozenSlots = DEFAULT_FROZEN_SLOTS;
            this.algorithm = algorithm;
            if (algorithm != ALGORITHM_DEFAULT) {
                computeLineSortingRules(rowSize,
                        algorithm == ALGORITHM_HORIZONTAL);
            }
        }

        this.rulePriority = new int[size];
        this.keywordOrder = new int[size];
        for (int i = 0; i < size; i++) {
            this.rulePriority[i] = -1;
            ItemStack stack = containerMgr.getItemStack(i);
            if (stack != null) {
                this.keywordOrder[i] = getItemOrder(stack);
            } else {
                this.keywordOrder[i] = -1;
            }
        }
    }

    public void sort() throws TimeoutException {

        // Do nothing if the inventory is closed
        // if (!mc.hrrentScreen instanceof GuiContainer)
        //      return;

        long timer = System.nanoTime();
        InvTweaksContainerManager globalContainer = new InvTweaksContainerManager(mc);

        // Put hold item down
        if (getHeldStack() != null) {
            int emptySlot = globalContainer.getFirstEmptyIndex(InvTweaksContainerSection.INVENTORY);
            if (emptySlot != -1) {
                globalContainer.putHoldItemDown(InvTweaksContainerSection.INVENTORY, emptySlot);
            }
            else {
                return; // Not enough room to work, abort
            }
        }

        if (algorithm != ALGORITHM_DEFAULT) {

            if (algorithm == ALGORITHM_EVEN_STACKS) {
                log.info("Distributing items.");

                //item and slot counts for each unique item
                HashMap<List<Integer>, int[]> itemCounts = new HashMap<List<Integer>, int[]>();
                for(int i = 0; i < size; i++) {
                    ItemStack stack = containerMgr.getItemStack(i);
                    if(stack != null) {
                        List<Integer> item = Arrays.asList(getItemID(stack), getItemDamage(stack));
                        int[] count = itemCounts.get(item);
                        if(count == null) {
                            int[] newCount = {getStackSize(stack), 1};
                            itemCounts.put(item,newCount);
                        } else {
                            count[0] += getStackSize(stack); //amount of item
                            count[1]++;                      //slots with item
                        }
                    }
                }

                //handle each unique item separately
                for(Entry<List<Integer>, int[]> entry : itemCounts.entrySet()) {
                    List<Integer> item = entry.getKey();
                    int[] count = entry.getValue();
                    int numPerSlot = count[0]/count[1]//totalNumber/numberOfSlots

                    //skip hacked itemstacks that are larger than their max size
                    //no idea why they would be here, but may as well account for them anyway
                    if(numPerSlot <= getMaxStackSize(new ItemStack(item.get(0),1,0))) {

                        //linkedlists to store which stacks have too many/few items
                        LinkedList<Integer> smallStacks = new LinkedList<Integer>();
                        LinkedList<Integer> largeStacks = new LinkedList<Integer>();
                        for(int i = 0; i < size; i++) {
                            ItemStack stack = containerMgr.getItemStack(i);
                            if(stack != null && Arrays.asList(getItemID(stack),getItemDamage(stack)).equals(item)) {
                                int stackSize = getStackSize(stack);
                                if(stackSize > numPerSlot)
                                    largeStacks.offer(i);
                                else if(stackSize < numPerSlot)
                                    smallStacks.offer(i);
                            }
                        }

                        //move items from stacks with too many to those with too little
                        while((!smallStacks.isEmpty())) {
                            int largeIndex = (Integer)largeStacks.peek();
                            int largeSize = getStackSize(containerMgr.getItemStack(largeIndex));
                            int smallIndex = (Integer)smallStacks.peek();
                            int smallSize = getStackSize(containerMgr.getItemStack(smallIndex));
                            containerMgr.moveSome(largeIndex, smallIndex, Math.min(numPerSlot-smallSize,largeSize-numPerSlot));

                            //update stack lists
                            largeSize = getStackSize(containerMgr.getItemStack(largeIndex));
                            smallSize = getStackSize(containerMgr.getItemStack(smallIndex));
                            if(largeSize == numPerSlot)
                                largeStacks.remove();
                            if(smallSize == numPerSlot)
                                smallStacks.remove();
                        }

                        //put all leftover into one stack for easy removal
                        while(largeStacks.size() > 1) {
                            int largeIndex = (Integer)largeStacks.poll();
                            int largeSize = getStackSize(containerMgr.getItemStack(largeIndex));
                            containerMgr.moveSome(largeIndex,(Integer)largeStacks.peek(),largeSize-numPerSlot);
                        }
                    }
                }

                //mark all items as moved. (is there a better way?)
                for(int i=0;i<size;i++)
                    markAsMoved(i,1);

            } else if (algorithm == ALGORITHM_INVENTORY) {
                //// Move items out of the crafting slots
                log.info("Handling crafting slots.");
                if (globalContainer.hasSection(InvTweaksContainerSection.CRAFTING_IN)) {
                    List<Slot> craftingSlots = globalContainer.getSlots(InvTweaksContainerSection.CRAFTING_IN);
                    int emptyIndex = globalContainer.getFirstEmptyIndex(InvTweaksContainerSection.INVENTORY);
                    if (emptyIndex != -1) {
                        for (Slot craftingSlot : craftingSlots) {
                            if (hasStack(craftingSlot)) {
                                globalContainer.move(
                                        InvTweaksContainerSection.CRAFTING_IN,
                                        globalContainer.getSlotIndex(getSlotNumber(craftingSlot)),
                                        InvTweaksContainerSection.INVENTORY,
                                        emptyIndex);
                                emptyIndex = globalContainer.getFirstEmptyIndex(InvTweaksContainerSection.INVENTORY);
                                if(emptyIndex == -1) {
                                    break;
                                }
                            }
                        }
                    }
                }


                //// Merge stacks to fill the ones in locked slots
                //// + Move armor parts to the armor slots

                log.info("Merging stacks.");
                for (int i = size - 1; i >= 0; i--) {
                    ItemStack  from = containerMgr.getItemStack(i);
                    if (from != null) {

                        // Move armor parts
                      Item fromItem = getItem(from);
                      if (isDamageable(fromItem)) {
                          if (sortArmorParts) {
                               if (isItemArmor(fromItem)) {
                                 ItemArmor fromItemArmor = asItemArmor(fromItem);
                                   if (globalContainer.hasSection(InvTweaksContainerSection.ARMOR)) {
                                       List<Slot> armorSlots = globalContainer.getSlots(InvTweaksContainerSection.ARMOR);
                                       for (Slot slot : armorSlots) {
                                        boolean move = false;
                                        if (!hasStack(slot)) {
                                          move = true;
                                        }
                                        else {
                                                Item currentArmor = getItem(getStack(slot));
                                                if(isItemArmor(currentArmor)) {
                                                    int armorLevel = getArmorLevel(asItemArmor(currentArmor));
                                                    if (armorLevel < getArmorLevel(fromItemArmor)
                                                            || (armorLevel == getArmorLevel(fromItemArmor)
                                                                    && getItemDamage(getStack(slot)) < getItemDamage(from))) {
                                                        move = true;
                                                    }
                                                } else {
                                                    move = true;
                                                }
                                        }
                                          if (areSlotAndStackCompatible(slot, from) && move) {
                                              globalContainer.move(InvTweaksContainerSection.INVENTORY, i, InvTweaksContainerSection.ARMOR,
                                                      globalContainer.getSlotIndex(getSlotNumber(slot)));
                                          }
                                      }
                                   }
                               }
                          }
                      }

                        // Stackable objects are never damageable
                        else {
                            int j = 0;
                            for (Integer lockPriority : lockPriorities) {
                                if (lockPriority > 0) {
                                    ItemStack to = containerMgr.getItemStack(j);
                                    if (to != null && areItemsEqual(from, to)) {
                                        move(i, j, Integer.MAX_VALUE);
                                        markAsNotMoved(j);
                                        if (containerMgr.getItemStack(i) == null) {
                                            break;
                                        }
                                    }
                                }
                                j++;
                            }
                        }
                    }
                }

            }

            //// Apply rules
            log.info("Applying rules.");

            // Sorts rule by rule, themselves being already sorted by decreasing priority
            Iterator<InvTweaksConfigSortingRule> rulesIt = rules.iterator();
            while (rulesIt.hasNext()) {

                InvTweaksConfigSortingRule rule = rulesIt.next();
                int rulePriority = rule.getPriority();

                if (log.getLevel() == InvTweaksConst.DEBUG)
                    log.info("Rule : "+rule.getKeyword()+"("+rulePriority+")");

                // For every item in the inventory
                for (int i = 0; i < size; i++) {
                    ItemStack from = containerMgr.getItemStack(i);

                    // If the rule is strong enough to move the item and it matches the item, move it
                    if (hasToBeMoved(i) && lockPriorities[i] < rulePriority) {
                        List<InvTweaksItemTreeItem> fromItems = tree.getItems(
                                getItemID(from), getItemDamage(from));
                        if (tree.matches(fromItems, rule.getKeyword())) {

                            // Test preffered slots
                            int[] preferredSlots = rule.getPreferredSlots();
                            int stackToMove = i;
                            for (int j = 0; j < preferredSlots.length; j++) {
                                int k = preferredSlots[j];

                                // Move the stack!
                                int moveResult = move(stackToMove, k, rulePriority);
                                if (moveResult != -1) {
                                    if (moveResult == k) {
                                        break;
                                    }
                                    else {
                                        from = containerMgr.getItemStack(moveResult);
                                        fromItems = tree.getItems(getItemID(from), getItemDamage(from));
                                        if (!tree.matches(fromItems, rule.getKeyword())) {
                                            break;
                                        }
                                        else {
                                            stackToMove = moveResult;
                                            j = -1;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            //// Don't move locked stacks
            log.info("Locking stacks.");

            for (int i = 0; i < size; i++) {
                if (hasToBeMoved(i) && lockPriorities[i] > 0) {
                    markAsMoved(i, 1);
                }
            }

        }

        //// Sort remaining
        defaultSorting();

        if (log.getLevel() == InvTweaksConst.DEBUG) {
            timer = System.nanoTime()-timer;
            log.info("Sorting done in " + timer + "ns");
        }

        //// Put hold item down, just in case
        if (getHeldStack() != null) {
            int emptySlot = globalContainer.getFirstEmptyIndex(InvTweaksContainerSection.INVENTORY);
            if (emptySlot != -1) {
                globalContainer.putHoldItemDown(InvTweaksContainerSection.INVENTORY, emptySlot);
            }
        }
    }

    private void defaultSorting() throws TimeoutException {

        log.info("Default sorting.");

        Vector<Integer> remaining = new Vector<Integer>(), nextRemaining = new Vector<Integer>();
        for (int i = 0; i < size; i++) {
            if (hasToBeMoved(i)) {
                remaining.add(i);
                nextRemaining.add(i);
            }
        }

        int iterations = 0;
        while (remaining.size() > 0 && iterations++ < 50) {
            for (int i : remaining) {
                if (hasToBeMoved(i)) {
                    for (int j = 0; j < size; j++) {
                        if (move(i, j, 1) != -1) {
                            nextRemaining.remove((Object) j);
                            break;
                        }
                    }
                }
                else {
                    nextRemaining.remove((Object) i);
                }
            }
            remaining.clear();
            remaining.addAll(nextRemaining);
        }
        if (iterations == 100) {
            log.warning("Sorting takes too long, aborting.");
        }

    }

    /**
     * Tries to move a stack from i to j, and swaps them if j is already
     * occupied but i is of greater priority (even if they are of same ID).
     *
     * @param i from slot
     * @param j to slot
     * @param priority  The rule priority. Use 1 if the stack was not moved using a rule.
     * @return -1 if it failed,
     *      j if the stacks were merged into one,
     *      n if the j stack has been moved to the n slot.
     * @throws TimeoutException
     */
    private int move(int i, int j, int priority) throws TimeoutException {

        ItemStack from = containerMgr.getItemStack(i), to = containerMgr.getItemStack(j);

        if (from == null || frozenSlots[j] || frozenSlots[i]) {
            return -1;
        }

        //log.info("Moving " + i + " (" + from + ") to " + j + " (" + to + ") ");

        if (lockPriorities[i] <= priority) {

            if (i == j) {
                markAsMoved(i, priority);
                return j;
            }

            // Move to empty slot
            if (to == null && lockPriorities[j] <= priority && !frozenSlots[j]) {
                rulePriority[i] = -1;
                keywordOrder[i] = -1;
                rulePriority[j] = priority;
                keywordOrder[j] = getItemOrder(from);
                containerMgr.move(i, j);
                return j;
            }

            // Try to swap/merge
            else if (to != null) {

                boolean canBeSwappedOrMerged = false;

                // Can be swapped?
                if (lockPriorities[j] <= priority) {
                    if (rulePriority[j] < priority) {
                        canBeSwappedOrMerged = true;
                    } else if (rulePriority[j] == priority) {
                        if (isOrderedBefore(i, j)) {
                            canBeSwappedOrMerged = true;
                        }
                    }
                }

                if (!hasDataTags(from) && !hasDataTags(to) && areItemsEqual(from, to)) {
                    // Can be merged?
                    if (getStackSize(to) < getMaxStackSize(to)) {
                        canBeSwappedOrMerged = true;
                    }
                    // Safety check (for TooManyItems)
                    else if (getStackSize(from) > getMaxStackSize(from)) {
                        canBeSwappedOrMerged = false;
                    }
                }

                if (canBeSwappedOrMerged) {

                    keywordOrder[j] = keywordOrder[i];
                    rulePriority[j] = priority;
                    rulePriority[i] = -1;
                    containerMgr.move(i, j);

                    ItemStack remains = containerMgr.getItemStack(i);

                    if (remains != null) {
                        int dropSlot = i;
                        if (lockPriorities[j] > lockPriorities[i]) {
                            for (int k = 0; k < size; k++) {
                                if (containerMgr.getItemStack(k) == null
                                        && lockPriorities[k] == 0) {
                                    dropSlot = k;
                                    break;
                                }
                            }
                        }
                        if (dropSlot != i) {
                            containerMgr.move(i, dropSlot);
                        }
                        rulePriority[dropSlot] = -1;
                        keywordOrder[dropSlot] = getItemOrder(remains);
                        return dropSlot;
                    }
                    else {
                        return j;
                    }
                }
            }

        }

        return -1;
    }

    private void markAsMoved(int i, int priority) {
        rulePriority[i] = priority;
    }

    private void markAsNotMoved(int i) {
        rulePriority[i] = -1;
    }

    private boolean hasToBeMoved(int slot) {
        return containerMgr.getItemStack(slot) != null
                && rulePriority[slot] == -1;
    }

    private boolean isOrderedBefore(int i, int j) {

        ItemStack iStack = containerMgr.getItemStack(i), jStack = containerMgr.getItemStack(j);

        if (jStack == null) {
            return true;
        } else if (iStack == null || keywordOrder[i] == -1) {
            return false;
        } else {
            if (keywordOrder[i] == keywordOrder[j]) {
                // Items of same keyword orders can have different IDs,
                // in the case of categories defined by a range of IDs
                if (getItemID(iStack) == getItemID(jStack)) {
                    if (getItemDamage(iStack) != getItemDamage(jStack)) {
                        if (isItemStackDamageable(iStack)) {
                            return getItemDamage(iStack) > getItemDamage(jStack);
                        }
                        else {
                            return getItemDamage(iStack) < getItemDamage(jStack);
                        }
                    }
                    else {
                        return getStackSize(iStack) > getStackSize(jStack);
                    }
                } else {
                    return getItemID(iStack) > getItemID(jStack);
                }
            } else {
                return keywordOrder[i] < keywordOrder[j];
            }
        }
    }

    private int getItemOrder(ItemStack itemStack) {
        List<InvTweaksItemTreeItem> items = tree.getItems(
                getItemID(itemStack), getItemDamage(itemStack));
        return (items != null && items.size() > 0)
                ? items.get(0).getOrder()
                : Integer.MAX_VALUE;
    }

    private void computeLineSortingRules(int rowSize, boolean horizontal) {

        rules = new Vector<InvTweaksConfigSortingRule>();


        Map<InvTweaksItemTreeItem, Integer> stats = computeContainerStats();
        List<InvTweaksItemTreeItem> itemOrder = new ArrayList<InvTweaksItemTreeItem>();

        int distinctItems = stats.size();
        int columnSize = getContainerColumnSize(rowSize);
        int spaceWidth;
        int spaceHeight;
        int availableSlots = size;
        int remainingStacks = 0;
        for (Integer stacks : stats.values()) {
            remainingStacks += stacks;
        }

        // No need to compute rules for an empty chest
        if (distinctItems == 0)
            return;

        // (Partially) sort stats by decreasing item stack count
        List<InvTweaksItemTreeItem> unorderedItems = new ArrayList<InvTweaksItemTreeItem>(stats.keySet());
        boolean hasStacksToOrderFirst = true;
        while (hasStacksToOrderFirst) {
            hasStacksToOrderFirst = false;
            for (InvTweaksItemTreeItem item : unorderedItems) {
                Integer value = stats.get(item);
                if (value > ((horizontal) ? rowSize : columnSize)
                        && !itemOrder.contains(item)) {
                    hasStacksToOrderFirst = true;
                    itemOrder.add(item);
                    unorderedItems.remove(item);
                    break;
                }
            }
        }
        Collections.sort(unorderedItems, Collections.reverseOrder());
        itemOrder.addAll(unorderedItems);

        // Define space size used for each item type.
        if (horizontal) {
            spaceHeight = 1;
            spaceWidth = rowSize/((distinctItems+columnSize-1)/columnSize);
        }
        else {
            spaceWidth = 1;
            spaceHeight = columnSize/((distinctItems+rowSize-1)/rowSize);
        }

        char row = 'a', maxRow = (char) (row - 1 + columnSize);
        char column = '1', maxColumn = (char) (column - 1 + rowSize);

        // Create rules
        Iterator<InvTweaksItemTreeItem> it = itemOrder.iterator();
        while (it.hasNext()) {

            InvTweaksItemTreeItem item = it.next();

            // Adapt rule dimensions to fit the amount
            int thisSpaceWidth = spaceWidth,
                thisSpaceHeight = spaceHeight;
            while (stats.get(item) > thisSpaceHeight*thisSpaceWidth) {
                if (horizontal) {
                    if (column + thisSpaceWidth < maxColumn) {
                        thisSpaceWidth = maxColumn - column + 1;
                    }
                    else if (row + thisSpaceHeight < maxRow) {
                        thisSpaceHeight++;
                    }
                    else {
                        break;
                    }
                }
                else {
                    if (row + thisSpaceHeight < maxRow) {
                        thisSpaceHeight = maxRow - row + 1;
                    }
                    else if (column + thisSpaceWidth < maxColumn) {
                        thisSpaceWidth++;
                    }
                    else {
                        break;
                    }
                }
            }

            // Adjust line/column ends to fill empty space
            if (horizontal && (column + thisSpaceWidth == maxColumn)) {
                thisSpaceWidth++;
            }
            else if (!horizontal && row + thisSpaceHeight == maxRow) {
                thisSpaceHeight++;
            }

            // Create rule
            String constraint = row + "" + column + "-"
                    + (char)(row - 1 + thisSpaceHeight)
                    + (char)(column - 1 + thisSpaceWidth);
            if (!horizontal) {
                constraint += 'v';
            }
            rules.add(new InvTweaksConfigSortingRule(tree, constraint, item.getName(), size, rowSize));

            // Check if ther's still room for more rules
            availableSlots -= thisSpaceHeight*thisSpaceWidth;
            remainingStacks -= stats.get(item);
            if (availableSlots >= remainingStacks) {
                // Move origin for next rule
                if (horizontal) {
                    if (column + thisSpaceWidth + spaceWidth <= maxColumn + 1) {
                        column += thisSpaceWidth;
                    }
                    else {
                        column = '1';
                        row += thisSpaceHeight;
                    }
                }
                else {
                    if (row + thisSpaceHeight + spaceHeight <= maxRow + 1) {
                        row += thisSpaceHeight;
                    }
                    else {
                        row = 'a';
                        column += thisSpaceWidth;
                    }
                }
                if (row > maxRow || column > maxColumn)
                    break;
            }
            else {
                break;
            }
        }

        String defaultRule;
        if (horizontal) {
            defaultRule = maxRow + "1-a" + maxColumn;
        }
        else {
            defaultRule = "a" + maxColumn + "-" + maxRow + "1v";
        }
        rules.add(new InvTweaksConfigSortingRule(tree, defaultRule,
                tree.getRootCategory().getName(), size, rowSize));

    }

    private Map<InvTweaksItemTreeItem, Integer> computeContainerStats() {
        Map<InvTweaksItemTreeItem, Integer> stats = new HashMap<InvTweaksItemTreeItem, Integer>();
        Map<Integer, InvTweaksItemTreeItem> itemSearch = new HashMap<Integer, InvTweaksItemTreeItem>();

        for (int i = 0; i < size; i++) {
            ItemStack stack = containerMgr.getItemStack(i);
            if (stack != null) {
                int itemSearchKey = getItemID(stack)*100000 +
                        ((getMaxStackSize(stack) != 1) ? getItemDamage(stack) : 0);
                InvTweaksItemTreeItem item = itemSearch.get(itemSearchKey);
                if (item == null) {
                    item = tree.getItems(getItemID(stack),
                            getItemDamage(stack)).get(0);
                    itemSearch.put(itemSearchKey, item);
                    stats.put(item, 1);
                }
                else {
                    stats.put(item, stats.get(item) + 1);
                }
            }
        }

        return stats;
    }

    private int getContainerColumnSize(int rowSize) {
        return size / rowSize;
    }

}
TOP

Related Classes of invtweaks.InvTweaksHandlerSorting

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.