/**
* Copyright (c) 2011-2015, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
* <p/>
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.transport.pipes;
import io.netty.buffer.ByteBuf;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import buildcraft.BuildCraftTransport;
import buildcraft.api.core.ISerializable;
import buildcraft.core.GuiIds;
import buildcraft.core.lib.inventory.InvUtils;
import buildcraft.core.lib.inventory.InventoryWrapper;
import buildcraft.core.lib.inventory.SimpleInventory;
import buildcraft.core.lib.inventory.StackHelper;
import buildcraft.core.lib.network.IGuiReturnHandler;
import buildcraft.core.lib.utils.NetworkUtils;
import buildcraft.transport.BlockGenericPipe;
import buildcraft.transport.PipeIconProvider;
public class PipeItemsEmerald extends PipeItemsWood implements ISerializable, IGuiReturnHandler {
public enum FilterMode {
WHITE_LIST, BLACK_LIST, ROUND_ROBIN
}
public class EmeraldPipeSettings {
private FilterMode filterMode;
public EmeraldPipeSettings() {
filterMode = FilterMode.WHITE_LIST;
}
public FilterMode getFilterMode() {
return filterMode;
}
public void setFilterMode(FilterMode mode) {
filterMode = mode;
}
public void readFromNBT(NBTTagCompound nbt) {
filterMode = FilterMode.values()[nbt.getByte("filterMode")];
}
public void writeToNBT(NBTTagCompound nbt) {
nbt.setByte("filterMode", (byte) filterMode.ordinal());
}
}
private EmeraldPipeSettings settings = new EmeraldPipeSettings();
private final SimpleInventory filters = new SimpleInventory(9, "Filters", 1);
private int currentFilter = 0;
public PipeItemsEmerald(Item item) {
super(item);
standardIconIndex = PipeIconProvider.TYPE.PipeItemsEmerald_Standard.ordinal();
solidIconIndex = PipeIconProvider.TYPE.PipeAllEmerald_Solid.ordinal();
}
@Override
public boolean blockActivated(EntityPlayer entityplayer, ForgeDirection side) {
if (entityplayer.getCurrentEquippedItem() != null) {
if (Block.getBlockFromItem(entityplayer.getCurrentEquippedItem().getItem()) instanceof BlockGenericPipe) {
return false;
}
}
if (super.blockActivated(entityplayer, side)) {
return true;
}
if (!container.getWorldObj().isRemote) {
entityplayer.openGui(BuildCraftTransport.instance, GuiIds.PIPE_EMERALD_ITEM, container.getWorldObj(), container.xCoord, container.yCoord, container.zCoord);
}
return true;
}
@Override
public ItemStack[] checkExtract(IInventory inventory, boolean doRemove, ForgeDirection from) {
if (inventory == null) {
return null;
}
// Handle possible double chests and wrap it in the ISidedInventory interface.
ISidedInventory sidedInventory = InventoryWrapper.getWrappedInventory(InvUtils.getInventory(inventory));
if (settings.getFilterMode() == FilterMode.ROUND_ROBIN) {
return checkExtractRoundRobin(sidedInventory, doRemove, from);
}
return checkExtractFiltered(sidedInventory, doRemove, from);
}
private ItemStack[] checkExtractFiltered(ISidedInventory inventory, boolean doRemove, ForgeDirection from) {
for (int k : inventory.getAccessibleSlotsFromSide(from.ordinal())) {
ItemStack stack = inventory.getStackInSlot(k);
if (stack == null || stack.stackSize <= 0) {
continue;
}
if (!inventory.canExtractItem(k, stack, from.ordinal())) {
continue;
}
boolean matches = isFiltered(stack);
boolean isBlackList = settings.getFilterMode() == FilterMode.BLACK_LIST;
if ((isBlackList && matches) || (!isBlackList && !matches)) {
continue;
}
if (doRemove) {
int maxStackSize = stack.stackSize;
int stackSize = Math.min(maxStackSize, battery.getEnergyStored() / 10);
if (stackSize > 0) {
speedMultiplier = Math.min(4.0F, battery.getEnergyStored() * 10 / stackSize);
int energyUsed = (int) (stackSize * 10 * speedMultiplier);
battery.useEnergy(energyUsed, energyUsed, false);
stack = inventory.decrStackSize(k, stackSize);
} else {
return null;
}
}
return new ItemStack[]{stack};
}
return null;
}
private ItemStack[] checkExtractRoundRobin(ISidedInventory inventory, boolean doRemove, ForgeDirection from) {
for (int i : inventory.getAccessibleSlotsFromSide(from.ordinal())) {
ItemStack stack = inventory.getStackInSlot(i);
if (stack != null && stack.stackSize > 0) {
ItemStack filter = getCurrentFilter();
if (filter == null) {
return null;
}
if (!StackHelper.isMatchingItemOrList(filter, stack)) {
continue;
}
if (!inventory.canExtractItem(i, stack, from.ordinal())) {
continue;
}
if (doRemove) {
// In Round Robin mode, extract only 1 item regardless of power level.
stack = inventory.decrStackSize(i, 1);
incrementFilter();
} else {
stack = stack.copy();
stack.stackSize = 1;
}
return new ItemStack[]{stack};
}
}
return null;
}
private boolean isFiltered(ItemStack stack) {
for (int i = 0; i < filters.getSizeInventory(); i++) {
ItemStack filter = filters.getStackInSlot(i);
if (filter == null) {
return false;
}
if (StackHelper.isMatchingItemOrList(filter, stack)) {
return true;
}
}
return false;
}
private void incrementFilter() {
currentFilter = (currentFilter + 1) % filters.getSizeInventory();
int count = 0;
while (filters.getStackInSlot(currentFilter) == null && count < filters.getSizeInventory()) {
currentFilter = (currentFilter + 1) % filters.getSizeInventory();
count++;
}
}
private ItemStack getCurrentFilter() {
ItemStack filter = filters.getStackInSlot(currentFilter);
if (filter == null) {
incrementFilter();
}
return filters.getStackInSlot(currentFilter);
}
public IInventory getFilters() {
return filters;
}
public EmeraldPipeSettings getSettings() {
return settings;
}
@Override
public void writeData(ByteBuf data) {
NBTTagCompound nbt = new NBTTagCompound();
filters.writeToNBT(nbt);
settings.writeToNBT(nbt);
NetworkUtils.writeNBT(data, nbt);
data.writeByte(currentFilter);
}
@Override
public void readData(ByteBuf data) {
NBTTagCompound nbt = NetworkUtils.readNBT(data);
filters.readFromNBT(nbt);
settings.readFromNBT(nbt);
currentFilter = data.readUnsignedByte();
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
filters.readFromNBT(nbt);
settings.readFromNBT(nbt);
currentFilter = nbt.getInteger("currentFilter") % filters.getSizeInventory();
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
filters.writeToNBT(nbt);
settings.writeToNBT(nbt);
nbt.setInteger("currentFilter", currentFilter);
}
@Override
public void writeGuiData(ByteBuf data) {
data.writeByte((byte) settings.getFilterMode().ordinal());
}
@Override
public void readGuiData(ByteBuf data, EntityPlayer sender) {
settings.setFilterMode(FilterMode.values()[data.readByte()]);
}
}