Files
Wizardry/src/main/java/electroblob/wizardry/inventory/VirtualSlot.java
T
Electroblob77 c161a74d73 Add bookshelf interface to arcane workbench
Implements the main functionality:
- Access bookshelves from within the workbench
- Search by spell name, tier, element and type
- Sort by tier, element or alphabetically, ascending or descending
- Three-way shift-clicking support
- Automatic return of books to bookshelves when wand is removed
2020-03-31 21:33:10 +01:00

80 lines
3.1 KiB
Java

package electroblob.wizardry.inventory;
import electroblob.wizardry.tileentity.TileEntityBookshelf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
/**
* A {@code VirtualSlot} represents a slot in an inventory other than the one that is currently open. Like regular slots,
* they hold a single {@link net.minecraft.item.ItemStack}, but unlike regular slots, they are not drawn to the screen
* and cannot be interacted with directly. A virtual slot is effectively a reference to a specific slot in some other
* inventory that allows the details of that inventory to be abstracted away from the current container.
* <p></p>
* <i>N.B. For normal slots, {@code slotIndex == slotNumber} (index is for the inventory, number is for the container).
* Importantly, for virtual slots this is <b>not the case</b>, since the {@code Container} they belong to is not the
* one associated with the virtual slot's {@code IInventory}.</i>
*/
public class VirtualSlot extends Slot {
private final TileEntity tileEntity;
public VirtualSlot(IInventory inventory, int index){
super(inventory, index, -999, -999);
if(!(inventory instanceof TileEntity)) throw new IllegalArgumentException("Inventory must be a tile entity!");
this.tileEntity = (TileEntity)inventory;
}
@Override
public boolean isEnabled(){
return false; // Virtual slots are never displayed
}
// We don't really want to be updating the bookshelves every single tick (let alone every frame!), so we're going
// to have to do some 'assuming things stay the same until told otherwise'. This means it's possible that virtual
// slots will remain even when their containers are gone, so we need a failsafe for when that happens.
/** Returns true if this slot is valid, i.e. the tile entity still exists. */
public boolean isValid(){
return !tileEntity.isInvalid();
}
// Normally the container decides if a stack is valid, but that's not going to work here
@Override
public boolean isItemValid(ItemStack stack){
// getSlotIndex() is required here, NOT slotNumber (which is only populated when the slot is added to a
// container - the javadoc is wrong, it has nothing to do with inventories)
return isValid() && inventory.isItemValidForSlot(getSlotIndex(), stack);
}
@Override
public boolean canTakeStack(EntityPlayer playerIn){
return isValid() && super.canTakeStack(playerIn);
}
@Override
public ItemStack onTake(EntityPlayer player, ItemStack stack){
return isValid() ? super.onTake(player, stack) : ItemStack.EMPTY;
}
@Override
public ItemStack getStack(){
return isValid() ? super.getStack() : ItemStack.EMPTY;
}
@Override
public void putStack(ItemStack stack){
if(isValid() && inventory instanceof TileEntityBookshelf) ((TileEntityBookshelf)inventory).sync();
if(isValid()) super.putStack(stack);
}
@Override
public ItemStack decrStackSize(int amount){
if(isValid() && inventory instanceof TileEntityBookshelf) ((TileEntityBookshelf)inventory).sync();
return isValid() ? super.decrStackSize(amount) : ItemStack.EMPTY;
}
}