User Tools

Site Tools


tutorial:inventory

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Next revisionBoth sides next revision
tutorial:inventory [2019/08/06 15:31] fudgetutorial:inventory [2019/08/07 06:59] fudge
Line 1: Line 1:
 ====== Storing items in a block as an Inventory ====== ====== Storing items in a block as an Inventory ======
 +Make sure you've [[tutorial:blockentity|made a block entity]] before reading this tutorial.  
 +
 The standard way to store items in a BlockEntity is to make it an ''Inventory'' The standard way to store items in a BlockEntity is to make it an ''Inventory''
 This allows hoppers (or other mods) to insert and extract items from your BlockEntity without any extra work.  This allows hoppers (or other mods) to insert and extract items from your BlockEntity without any extra work. 
Line 110: Line 112:
 } }
 </code> </code>
 +
 Now in your ''BlockEntity'' Implement ''ImplementedInventory'',  Now in your ''BlockEntity'' Implement ''ImplementedInventory'', 
 and provide it with an instance of ''DefaultedList<ItemStack> items'' that stores the items. and provide it with an instance of ''DefaultedList<ItemStack> items'' that stores the items.
Line 121: Line 124:
         return items;         return items;
     }     }
-    ...+    [...]
  
 } }
  
 </code> </code>
--->>>>>>>Remember markDirty() <<<<<<<<<--  
 We're also gonna need to save the inventories to tag and load it from there.  We're also gonna need to save the inventories to tag and load it from there. 
 ''Inventories'' has helper methods that makes this very easy: ''Inventories'' has helper methods that makes this very easy:
 <code java> <code java>
 public class DemoBlockEntity extends BlockEntity implements ImplementedInventory { public class DemoBlockEntity extends BlockEntity implements ImplementedInventory {
-    ...+    [...]
     @Override     @Override
     public void fromTag(CompoundTag tag) {     public void fromTag(CompoundTag tag) {
Line 145: Line 147:
 } }
 </code> </code>
-===== Extracting and inserting from your inventory ===== +===== Extracting and inserting from your inventory (or any inventory) ===== 
-Remember that the same thing can be done with any inventory...+In our block class, we'll override the `activate` behavior to insert and extract items from our inventory.  
 +Note that this can be done to any ''Inventory'' instance, not just our own (so you could do the same thing to a chest block, for example). 
 +First we'll handle inserting into the inventory. The player will insert the item he is holding if he is holding one. 
 +It'll go into the first slot if it is empty, or to the second slot if the first one is empty,  
 +or if the second is empty too we'll print some information about the inventory 
 +Note that we call ''copy()'' when inserting the ''ItemStack'' into the inventory so it doesn't get destroyed alongside the player's ''ItemStack''
 +<code java> 
 +public class ExampleBlock extends Block implements BlockEntityProvider { 
 +    [...] 
 +    @Override 
 +    public boolean activate(BlockState blockState, World world, BlockPos blockPos, PlayerEntity player, Hand hand, BlockHitResult blockHitResult) { 
 +        if (world.isClient) return true; 
 +        Inventory blockEntity = (Inventory) world.getBlockEntity(blockPos); 
 + 
 + 
 +        if (!player.getStackInHand(hand).isEmpty()) { 
 +            // Check what is the first open slot and put an item from the player's hand there 
 +            if (blockEntity.getInvStack(0).isEmpty()) { 
 +                // Put the stack the player is holding into the inventory 
 +                blockEntity.setInvStack(0, player.getStackInHand(hand).copy()); 
 +                // Remove the stack from the player's hand 
 +                player.getStackInHand(hand).setCount(0); 
 +            } else if (blockEntity.getInvStack(1).isEmpty()) { 
 +                blockEntity.setInvStack(1, player.getStackInHand(hand).copy()); 
 +                player.getStackInHand(hand).setCount(0); 
 +            } else { 
 +                // If the inventory is full we'll print it's contents 
 +                System.out.println("The first slot holds " 
 +                        + blockEntity.getInvStack(0) + " and the second slot holds " + blockEntity.getInvStack(1)); 
 +            } 
 +        }  
 +        return true; 
 +    } 
 +
 +</code> 
 + 
 + 
 +We'll have the opposite behavior when the player is not holding an item. We'll take the item from the second slot, and then the first one of the second is empty.  
 +If the first is empty as well we won't do anything. 
 +<code java> 
 +public class ExampleBlock extends Block implements BlockEntityProvider { 
 +    [...] 
 +    @Override 
 +    public boolean activate(BlockState blockState, World world, BlockPos blockPos, PlayerEntity player, Hand hand, BlockHitResult blockHitResult) { 
 +        ... 
 +        if (!player.getStackInHand(hand).isEmpty()) { 
 +            ... 
 +        } else { 
 +            // If the player is not holding anything we'll get give him the items in the block entity one by one 
 + 
 +            // Find the first slot that has an item and give it to the player 
 +            if (!blockEntity.getInvStack(1).isEmpty()) { 
 +                // Give the player the stack in the inventory 
 +                player.giveItemStack(blockEntity.getInvStack(1)); 
 +                // Remove the stack from the inventory 
 +                blockEntity.removeInvStack(1); 
 +            } else if (!blockEntity.getInvStack(0).isEmpty()) { 
 +                player.giveItemStack(blockEntity.getInvStack(0)); 
 +                blockEntity.removeInvStack(0); 
 +            } 
 +        } 
 +         
 +        return true; 
 +    } 
 +
 +</code> 
 + 
 +===== Implementing SidedInventory ===== 
 +If you want to have different logic based on what side things (hopper or other mods) interact with your block  
 +you need to implement ''SidedInventory''.  
 +If say you wanted to make it so you cannot insert from the upper side of the block, you would do this: 
 +<code java> 
 +public class DemoBlockEntity extends BlockEntity implements ImplementedInventory, SidedInventory { 
 +    [...] 
 +    @Override 
 +    public int[] getInvAvailableSlots(Direction var1) { 
 +        // Just return an array of all slots 
 +        int[] result = new int[getItems().size()]; 
 +        for (int i = 0; i < result.length; i++) { 
 +            result[i] = i; 
 +        } 
 + 
 +        return result; 
 +    } 
 + 
 +    @Override 
 +    public boolean canInsertInvStack(int slot, ItemStack stack, Direction direction) { 
 +        return direction != Direction.UP; 
 +    } 
 + 
 +    @Override 
 +    public boolean canExtractInvStack(int slot, ItemStack stack, Direction direction) { 
 +        return true; 
 +    } 
 +
 + 
 +</code> 
tutorial/inventory.txt · Last modified: 2023/11/06 23:28 by binaris00