Package net.mcft.copy.betterstorage.inventory

Source Code of net.mcft.copy.betterstorage.inventory.InventoryCratePlayerView$MapData

package net.mcft.copy.betterstorage.inventory;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;

import net.mcft.copy.betterstorage.api.crate.ICrateWatcher;
import net.mcft.copy.betterstorage.misc.Constants;
import net.mcft.copy.betterstorage.misc.ItemIdentifier;
import net.mcft.copy.betterstorage.tile.crate.CratePileData;
import net.mcft.copy.betterstorage.tile.crate.TileEntityCrate;
import net.mcft.copy.betterstorage.utils.StackUtils;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;

/** An inventory interface built for players accessing crate piles. */
public class InventoryCratePlayerView extends InventoryBetterStorage implements ICrateWatcher {
 
  private static final int inventoryMaxSize = 9 * 6;
 
  private static class MapData {
    public int itemCount = 0;
  }
 
  public final CratePileData data;
  public final TileEntityCrate crate;
 
  private ItemStack[] tempContents;
  private Map<ItemIdentifier, MapData> countData = new HashMap<ItemIdentifier, MapData>();
  
  private boolean ignoreModifiedItems = false;
 
  public InventoryCratePlayerView(TileEntityCrate crate) {
    super(Constants.containerCrate);
    this.data = crate.getPileData();
    this.crate = crate;
   
    int size = Math.min(data.getCapacity(), inventoryMaxSize);
    tempContents = new ItemStack[size];
   
    // Fill temp contents with some random items from the crate pile.
    List<Integer> slotAccess = new ArrayList<Integer>(size);
    for (int i = 0; i < size; i++) slotAccess.add(i);
    if (data.getOccupiedSlots() < size) Collections.shuffle(slotAccess);
   
    Iterator<ItemStack> iter = data.getContents().getRandomStacks().iterator();
    for (int slot = 0; ((slot < size) && iter.hasNext()); slot++) {
      ItemStack stack = iter.next();
      getMapData(stack).itemCount += stack.stackSize;
      tempContents[slotAccess.get(slot)] = stack;
    }
  }
 
  // Map data related functions
 
  private MapData getMapData(ItemIdentifier item) {
    MapData data = countData.get(item);
    if (data != null) return data;
    data = new MapData();
    countData.put(item, data);
    return data;
  }
  private MapData getMapData(ItemStack item) {
    return getMapData(new ItemIdentifier(item));
  }
 
  // IInventory implementation
 
  @Override
  public int getSizeInventory() { return tempContents.length; }
 
  @Override
  public ItemStack getStackInSlot(int slot) {
    if ((slot < 0) || (slot >= getSizeInventory())) return null;
    return tempContents[slot];
  }
 
  @Override
  public void setInventorySlotContents(int slot, ItemStack stack) {
    if ((slot < 0) || (slot >= getSizeInventory())) return;
    ItemStack oldStack = getStackInSlot(slot);
    ignoreModifiedItems = true;
    if (oldStack != null) {
      ItemIdentifier item = new ItemIdentifier(oldStack);
      getMapData(item).itemCount -= oldStack.stackSize;
      data.removeItems(item, oldStack.stackSize);
    }
    if (stack != null) {
      int amount = Math.min(stack.stackSize,
          Math.min(data.getSpaceForItem(stack),
                   stack.getMaxStackSize()));
      if (amount <= 0) return;
      stack = StackUtils.copyStack(stack.copy(), amount);
      getMapData(stack).itemCount += amount;
      data.addItems(stack);
    }
    ignoreModifiedItems = false;
    tempContents[slot] = stack;
    if (stack == null)
      onSlotEmptied(slot);
  }
 
  @Override
  public ItemStack decrStackSize(int slot, int amount) {
    ItemStack stack = getStackInSlot(slot);
    if (stack == null) return null;
    amount = Math.min(amount, stack.stackSize);
   
    ItemIdentifier item = new ItemIdentifier(stack);
    getMapData(item).itemCount -= amount;
   
    stack.stackSize -= amount;
    if (stack.stackSize <= 0)
      tempContents[slot] = null;
   
    ignoreModifiedItems = true;
    ItemStack result = data.removeItems(item, amount);
    ignoreModifiedItems = false;
   
    if (tempContents[slot] == null)
      onSlotEmptied(slot);
   
    return result;
  }
 
  @Override
  public boolean isUseableByPlayer(EntityPlayer player) {
    int x = crate.xCoord;
    int y = crate.yCoord;
    int z = crate.zCoord;
    return ((player.worldObj.getTileEntity(x, y, z) == crate) &&
        (player.getDistanceSq(x + 0.5, y + 0.5, z + 0.5) < 64.0) &&
        (getSizeInventory() <= data.getCapacity()));
  }
 
  @Override
  public void markDirty() { }
 
  @Override
  public void openInventory() { data.addWatcher(this); }
  @Override
  public void closeInventory() { data.removeWatcher(this); }
 
  // ICrateWatcher implementation
 
  @Override
  public void onCrateItemsModified(ItemStack changed) {
    if (ignoreModifiedItems) return;
   
    ItemIdentifier item = new ItemIdentifier(changed);
    int amount = changed.stackSize;
   
    MapData itemData = getMapData(item);
    Queue<Integer> emptySlots = new LinkedList<Integer>();
   
    for (int slot = 0; slot < tempContents.length; slot++) {
      ItemStack stack = tempContents[slot];
      if (stack == null) { emptySlots.add(slot); continue; }
      if (!item.matches(stack)) continue;
      amount -= modifyItemsInSlot(slot, stack, itemData, amount);
      if (amount == 0) return;
    }
   
    while ((amount > 0) && (emptySlots.size() > 0))
      amount -= setItemsInSlot(emptySlots.poll(), item, itemData, amount);
  }
 
  // Misc functions
 
  /** Returns if at least 1 item from the stack could be
   *  stored in the player view, but doesn't change anything. */
  public boolean canFitSome(ItemStack item) {
    for (ItemStack stack : tempContents) {
      if ((stack == null) || (StackUtils.matches(stack, item) &&
                              (stack.stackSize < stack.getMaxStackSize())))
        return true;
    }
    return false;
  }
 
  private void onSlotEmptied(int slot) {
    int emptySlots = 0;
    for (int s = 0; s < tempContents.length; s++)
      if (tempContents[s] == null) emptySlots++;
   
    if (emptySlots <= data.getFreeSlots()) return;
   
    for (ItemStack stack : data.getContents().getItems()) {
      ItemIdentifier item = new ItemIdentifier(stack);
      MapData itemData = getMapData(item);
     
      int count = (stack.stackSize - itemData.itemCount);
      if (count <= 0) continue;
      setItemsInSlot(slot, item, itemData, count);
    }
  }
 
  private int modifyItemsInSlot(int slot, ItemStack stack, MapData itemData, int amount) {
    int count = Math.max(-stack.stackSize, Math.min(amount, stack.getMaxStackSize() - stack.stackSize));
    if ((stack.stackSize += count) <= 0)
      tempContents[slot] = null;
    itemData.itemCount += count;
    return count;
  }
 
  private int setItemsInSlot(int slot, ItemIdentifier item, MapData itemData, int maxAmount) {
    int size = Math.min(maxAmount, item.createStack(1).getMaxStackSize());
    tempContents[slot] = item.createStack(size);
    itemData.itemCount += size;
    return size;
  }
 
}
TOP

Related Classes of net.mcft.copy.betterstorage.inventory.InventoryCratePlayerView$MapData

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.