Package net.mcft.copy.betterstorage.inventory

Source Code of net.mcft.copy.betterstorage.inventory.InventoryCraftingStation

package net.mcft.copy.betterstorage.inventory;

import java.util.Arrays;

import net.mcft.copy.betterstorage.api.crafting.BetterStorageCrafting;
import net.mcft.copy.betterstorage.api.crafting.ContainerInfo;
import net.mcft.copy.betterstorage.api.crafting.CraftingSourceTileEntity;
import net.mcft.copy.betterstorage.api.crafting.ICraftingSource;
import net.mcft.copy.betterstorage.api.crafting.IRecipeInput;
import net.mcft.copy.betterstorage.api.crafting.StationCrafting;
import net.mcft.copy.betterstorage.config.GlobalConfig;
import net.mcft.copy.betterstorage.item.recipe.VanillaStationCrafting;
import net.mcft.copy.betterstorage.tile.entity.TileEntityCraftingStation;
import net.mcft.copy.betterstorage.utils.InventoryUtils;
import net.mcft.copy.betterstorage.utils.StackUtils;
import net.mcft.copy.betterstorage.utils.WorldUtils;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent;

public class InventoryCraftingStation extends InventoryBetterStorage {
 
  public TileEntityCraftingStation entity = null;
 
  public final ItemStack[] crafting;
  public final ItemStack[] output;
  public final ItemStack[] contents;
 
  public final ItemStack[] lastOutput;
 
  public StationCrafting currentCrafting = null;
  public boolean outputIsReal = false;
  public int progress = 0;
 
  private boolean hasRequirements = false;
  private boolean checkHasRequirements = true;
 
  public InventoryCraftingStation(TileEntityCraftingStation entity) {
    this("", entity.crafting, entity.output, entity.contents);
    this.entity = entity;
  }
  public InventoryCraftingStation(String name) {
    this(name, new ItemStack[9], new ItemStack[9], new ItemStack[18]);
  }
  private InventoryCraftingStation(String name, ItemStack[] crafting, ItemStack[] output, ItemStack[] contents) {
    super(name);
    this.crafting = crafting;
    this.output = output;
    this.contents = contents;
    lastOutput = new ItemStack[output.length];
  }
 
  public void update() {
    if (!outputIsReal && (currentCrafting != null) &&
        (((progress < currentCrafting.getCraftingTime()) ||
          (progress < GlobalConfig.stationAutocraftDelaySetting.getValue())))) progress++;
  }
 
  /** Called whenever the crafting input changes. */
  public void inputChanged() {
    progress = 0;
    currentCrafting = BetterStorageCrafting.findMatchingStationCrafting(crafting);
    if (currentCrafting == null)
      currentCrafting = VanillaStationCrafting.findVanillaRecipe(this);
    if (!outputIsReal) {
      if (currentCrafting != null) {
        ItemStack[] craftingOutput = currentCrafting.getOutput();
        for (int i = 0; i < output.length; i++)
          output[i] = ((i < craftingOutput.length) ? ItemStack.copyItemStack(craftingOutput[i]) : null);
      } else Arrays.fill(output, null);
      updateLastOutput();
    }
  }
 
  /** Called when an item is removed from the output
   *  slot while it doesn't store any real items. */
  public void craft(EntityPlayer player) {
    boolean hasRequirements = hasItemRequirements();
    ICraftingSource source = new CraftingSourceTileEntity(entity, player);
    currentCrafting.craft(source);
    IRecipeInput[] requiredInput = currentCrafting.getCraftRequirements();
    for (int i = 0; i < crafting.length; i++)
      if (crafting[i] != null)
        crafting[i] = craftSlot(crafting[i], requiredInput[i], player, false);
    int requiredExperience = currentCrafting.getRequiredExperience();
    if ((requiredExperience != 0) && (player != null) && !player.capabilities.isCreativeMode)
      player.experienceLevel -= requiredExperience;
    if (hasRequirements)
      pullRequired(requiredInput, false);
    outputIsReal = !outputEmpty();
    progress = 0;
    inputChanged();
    checkHasRequirements = true;
  }
 
  private ItemStack craftSlot(ItemStack stack, IRecipeInput requiredInput, EntityPlayer player, boolean simulate) {
    if (simulate) stack = stack.copy();
    ContainerInfo containerInfo = new ContainerInfo();
    requiredInput.craft(stack, containerInfo);
    ItemStack containerItem = ItemStack.copyItemStack(containerInfo.getContainerItem());
   
    boolean removeStack = false;
    if (stack.stackSize <= 0) {
      // Item stack is depleted.
      removeStack = true;
    } else if (stack.getItem().isDamageable() && (stack.getItemDamage() > stack.getMaxDamage())) {
      // Item stack is destroyed.
      removeStack = true;
      if (player != null)
        MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(player, stack));
    }
   
    // If the stack has been depleted, set it
    // to either null, or the container item.
    if (removeStack) {
      if (!containerInfo.doesLeaveCrafting()) {
        stack = containerItem;
        containerItem = null;
      } else stack = null;
    }
   
    if ((containerItem != null) && !simulate) {
      // Try to add the container item to the internal storage, or spawn the item in the world.
      if (!InventoryUtils.tryAddItemToInventory(containerItem, new InventoryStacks(contents), true) && (entity != null))
        WorldUtils.spawnItem(entity.getWorldObj(), entity.xCoord + 0.5, entity.yCoord + 0.5, entity.zCoord + 0.5, containerItem);
    }
    return stack;
  }
 
  /** Pull items required for the recipe from the internal inventory. Returns if successful. */
  public boolean pullRequired(IRecipeInput[] requiredInput, boolean simulate) {
    ItemStack[] contents = (simulate ? this.contents.clone() : this.contents);
    ItemStack[] crafting = (simulate ? this.crafting.clone() : this.crafting);
    boolean success = true;
    craftingLoop:
    for (int i = 0; i < crafting.length; i++) {
      ItemStack stack = crafting[i];
      IRecipeInput required = requiredInput[i];
      if (required != null) {
        int currentAmount = 0;
        if ((stack != null) && simulate)
          stack = craftSlot(stack, required, null, true);
        if (stack != null) {
          if (!required.matches(stack)) return false;
          currentAmount = stack.stackSize;
        }
        int requiredAmount = (required.getAmount() - currentAmount);
        if (requiredAmount <= 0) continue;
        for (int j = 0; j < contents.length; j++) {
          ItemStack contentsStack = contents[j];
          if (contentsStack == null) continue;
          if ((stack == null) ? required.matches(contentsStack)
                              : StackUtils.matches(stack, contentsStack)) {
            int amount = Math.min(contentsStack.stackSize, requiredAmount);
            crafting[i] = stack = StackUtils.copyStack(contentsStack, (currentAmount += amount));
            contents[j] =         StackUtils.copyStack(contentsStack, contentsStack.stackSize - amount);
            if ((requiredAmount -= amount) <= 0)
              continue craftingLoop;
          }
        }
      } else if (stack == null)
        continue;
      success = false;
      if (!simulate) break;
    }
    return success;
  }
 
  /** Returns if items can be taken out of the output slots. */
  public boolean canTake(EntityPlayer player) {
    return (outputIsReal || ((currentCrafting != null) &&
                             (currentCrafting.canCraft(new CraftingSourceTileEntity(entity, player))) &&
                             (progress >= currentCrafting.getCraftingTime()) && hasRequiredExperience(player) &&
                              ((player != null) || ((progress >= GlobalConfig.stationAutocraftDelaySetting.getValue()) &&
                                                    hasItemRequirements()))));
  }
 
  private boolean hasRequiredExperience(EntityPlayer player) {
    int requiredExperience = currentCrafting.getRequiredExperience();
    return ((requiredExperience == 0) ||
            ((player != null) && (player.capabilities.isCreativeMode ||
                                  (player.experienceLevel >= requiredExperience))));
  }
 
  /** Returns if the crafting station has the items
   *  required in its inventory to craft the recipe again. */
  public boolean hasItemRequirements() {
    if (checkHasRequirements) {
      hasRequirements = pullRequired(currentCrafting.getCraftRequirements(), true);
      checkHasRequirements = false;
    }
    return hasRequirements;
  }
 
  // IInventory implementation
 
  @Override
  public int getSizeInventory() { return (crafting.length + output.length + contents.length); }
 
  @Override
  public ItemStack getStackInSlot(int slot) {
    if (slot < crafting.length) return crafting[slot];
    else if (slot < crafting.length + output.length)
      return output[slot - crafting.length];
    else return contents[slot - (crafting.length + output.length)];
  }
  @Override
  public void setInventorySlotContents(int slot, ItemStack stack) {
    if (slot < crafting.length) crafting[slot] = stack;
    else if (slot < crafting.length + output.length)
      output[slot - crafting.length] = stack;
    else contents[slot - (crafting.length + output.length)] = stack;
    markDirty();
  }
 
  @Override
  public boolean isUseableByPlayer(EntityPlayer player) { return true; }
 
  @Override
  public void openInventory() {  }
  @Override
  public void closeInventory() {  }
 
  @Override
  public void markDirty() {
   
    if (entity != null)
      entity.markDirtySuper();
   
    // Craft the items if the ghost output was changed.
    if (outputChanged() && !outputIsReal &&
        (currentCrafting != null) && (entity != null))
      craft(null);
   
    // If the output is empty..
    if (outputEmpty()) {
      // ..set the output to not contain any real items.
      outputIsReal = false;
      if (currentCrafting != null) {
        // ..fill the output with ghost output from the recipe.
        ItemStack[] recipeOutput = currentCrafting.getOutput();
        for (int i = 0; i < recipeOutput.length; i++)
          output[i] = ItemStack.copyItemStack(recipeOutput[i]);
      }
      updateLastOutput();
    }
   
    checkHasRequirements = true;
   
  }
 
  // Utility functions

  private void updateLastOutput() {
    for (int i = 0; i < output.length; i++)
      lastOutput[i] = ItemStack.copyItemStack(output[i]);
  }
  private boolean outputChanged() {
    for (int i = 0; i < output.length; i++)
      if (!ItemStack.areItemStacksEqual(output[i], lastOutput[i]))
        return true;
    return false;
  }
  private boolean outputEmpty() {
    for (int i = 0; i < output.length; i++)
      if (output[i] != null) return false;
    return true;
  }
 
}
TOP

Related Classes of net.mcft.copy.betterstorage.inventory.InventoryCraftingStation

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.