Search in sources :

Example 1 with ItemEntry

use of buildcraft.api.transport.pipe.PipeEventItem.ItemEntry in project BuildCraft by BuildCraft.

the class PipeBehaviourDiamondItem method split.

@PipeEventHandler
public void split(PipeEventItem.Split split) {
    EnumFacing[] allSides = split.getAllPossibleDestinations().toArray(new EnumFacing[0]);
    if (allSides.length == 0 || allSides.length == 1) {
        // Nothing to split
        return;
    }
    ItemEntry[] items = split.items.toArray(new ItemEntry[0]);
    split.items.clear();
    // Note that the order doesn't matter
    for (ItemEntry item : items) {
        int[] countPerSide = new int[allSides.length];
        int totalCount = 0;
        for (int s = 0; s < allSides.length; s++) {
            int offset = FILTERS_PER_SIDE * allSides[s].ordinal();
            for (int i = 0; i < FILTERS_PER_SIDE; i++) {
                ItemStack compareTo = filters.getStackInSlot(offset + i);
                if (compareTo.isEmpty())
                    continue;
                if (StackUtil.isMatchingItemOrList(compareTo, item.stack)) {
                    int count = compareTo.getCount();
                    totalCount += count;
                    countPerSide[s] += count;
                }
            }
        }
        if (totalCount == 0) {
            totalCount = allSides.length;
            Arrays.fill(countPerSide, 1);
        } else {
            int hcf = countPerSide[0];
            for (int c : countPerSide) {
                hcf = MathUtil.findHighestCommonFactor(hcf, c);
            }
            if (hcf != 1) {
                totalCount /= hcf;
                for (int i = 0; i < countPerSide.length; i++) {
                    countPerSide[i] /= hcf;
                }
            }
        }
        /* If the stack count is divisible by the possible directions then we can just split the stack up evenly -
             * making the distribution perfect. */
        ItemEntry[] entries = new ItemEntry[allSides.length];
        ItemStack toSplit = item.stack;
        if (toSplit.getCount() >= totalCount) {
            int leftOver = toSplit.getCount() % totalCount;
            int multiples = (toSplit.getCount() - leftOver) / totalCount;
            for (int s = 0; s < allSides.length; s++) {
                ItemStack toSide = toSplit.copy();
                toSide.setCount(countPerSide[s] * multiples);
                entries[s] = new ItemEntry(item.colour, toSide, item.from);
                List<EnumFacing> dests = new ArrayList<>(1);
                dests.add(allSides[s]);
                entries[s].to = dests;
            }
            toSplit.setCount(leftOver);
        }
        if (!toSplit.isEmpty()) {
            int[] randLookup = new int[totalCount];
            int j = 0;
            for (int s = 0; s < allSides.length; s++) {
                int len = countPerSide[s];
                Arrays.fill(randLookup, j, j + len, s);
                j += len;
            }
            while (!toSplit.isEmpty()) {
                // Pick a random number between 0 and total count.
                int rand = split.holder.getPipeWorld().rand.nextInt(totalCount);
                int face = randLookup[rand];
                if (entries[face] == null) {
                    ItemStack stack = toSplit.copy();
                    stack.setCount(1);
                    ItemEntry entry = new ItemEntry(item.colour, stack, item.from);
                    List<EnumFacing> dests = entry.to = new ArrayList<>(1);
                    dests.add(allSides[face]);
                    entries[face] = entry;
                } else {
                    entries[face].stack.grow(1);
                }
                toSplit.shrink(1);
            }
        }
        for (int s = 0; s < allSides.length; s++) {
            ItemEntry entry = entries[s];
            if (entry == null) {
                continue;
            }
            split.items.add(entry);
        }
    }
}
Also used : EnumFacing(net.minecraft.util.EnumFacing) ArrayList(java.util.ArrayList) ItemStack(net.minecraft.item.ItemStack) ItemEntry(buildcraft.api.transport.pipe.PipeEventItem.ItemEntry) PipeEventHandler(buildcraft.api.transport.pipe.PipeEventHandler)

Aggregations

PipeEventHandler (buildcraft.api.transport.pipe.PipeEventHandler)1 ItemEntry (buildcraft.api.transport.pipe.PipeEventItem.ItemEntry)1 ArrayList (java.util.ArrayList)1 ItemStack (net.minecraft.item.ItemStack)1 EnumFacing (net.minecraft.util.EnumFacing)1