[1.7.2]Container - transferStackInSlot и mergeItemStack

771
5
Ребят, кто-то может объяснить, как нормально организовать transferStackInSlot и как работает mergeItemStack?
Если не сложно, но можете с примером(у меня в контейнере один слот, но в него нельзя ничего класть).
 
2,955
12
Ну смотри, ты там делаешь проверки, и взависимости от них ретурнишь слот. В печке предмет проверяется на горючесть, если горит - в нижний слот. И т.д. и т.к.
 
675
2
Цитата:
transferStackInSlot must be overrode in container classes or else crashes when happen when it is attempted. Now, mergeItemStack is a fancy boolean method that attempts to merge the given ItemStack into the slots within the given range (x, y-1) and can be flagged for whether it should start at the beginning of the container's inventory or the end (true for the end). mergeItemStack will return true if the stack can be merged and false if it can't (often accompanied by return null in an if block to make transferStackInSlot do nothing). So, for an example, mergeItemStack(new ItemStack(Item.diamond, 3), 11, 48, false) will do search the slots in the inventorySlots list from 11 to 47 (in your case, this will be the player's 36-slot inventory because your block's container is taking up slots 0 to 10 in the list) and it will start from the beginning slot in that range. Let's just set up an example player inventory for now.
Spoiler: 
Slot 1: 12 Dirt
Slot 2: 17 Iron Ingots
Slot 3: Empty
Slot 4: 63 Diamonds
Slot 5: 64 Diamonds
mergeItemStack will first search for the first slot that contains a like itemstack being merged (3 diamonds, remember?). Once it finds a suitable slot (slot 4 contains 63 diamonds, which matches the request) it will place as many items as it can into that slot (1) and with the remaining it will attempt to find more matching itemstacks. 64 diamonds matches, but it is full so it will go to the next stage. If there are no suitable itemstacks to merge with but there are still items left, it will begin searching that range again and look for the empty slots. So the remaining two diamonds will be put into the third slot!

Look through the other Containers in vanilla, specifically Furnace and Brewing Stand. Their transferStackInSlot methods provide pretty good detail on how certain item types behave when shift clicked (fuels will go to the fuel slot, brewing ingredients go to ingredient slot). I would begin by copying on of those methods verbatim and then replacing the if(slotNumber == #) with the specific things you're trying to do.

Happy modding. 
smile.png
 
 
771
5
Фух, разобрался.​
Вот мой рабочий код, который перемещает стаки по инвентарю, но не кладет в один мой слот:​

Код:
public ItemStack transferStackInSlot(EntityPlayer player, int slot){
        ItemStack iStack = null;
        Slot slotObject = (Slot)inventorySlots.get(slot);
        if(slotObject != null && slotObject.getHasStack()){
            ItemStack stackInSlot = slotObject.getStack();
            iStack = stackInSlot.copy();
            Esoteric.logger.error(slot);
            if(slot == 0){
                if(!mergeItemStack(stackInSlot, 1, 37, true)){
                    return null;
                }
            }else if(slot >= 28 && slot <= 37 && !mergeItemStack(stackInSlot, 1, 28, false)){
                return null;
            }else if(slot >= 0 && slot <= 27 && !mergeItemStack(stackInSlot, 28, 37, false)){
                return null;
            }
            if(stackInSlot.stackSize == 0){
                slotObject.putStack(null);
            }else{
                slotObject.onSlotChanged();
            }
            if(stackInSlot.stackSize == iStack.stackSize){
                return null;
            }
            slotObject.onPickupFromSlot(player, stackInSlot);
        }
        return iStack;
    }
 
Сверху