Package mekanism.common.tile

Source Code of mekanism.common.tile.TileEntityDigitalMiner

package mekanism.common.tile;

import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import mekanism.api.Coord4D;
import mekanism.api.Range4D;
import mekanism.common.HashList;
import mekanism.common.IActiveState;
import mekanism.common.IAdvancedBoundingBlock;
import mekanism.common.ILogisticalTransporter;
import mekanism.common.IRedstoneControl;
import mekanism.common.ISustainedData;
import mekanism.common.IUpgradeTile;
import mekanism.common.Mekanism;
import mekanism.common.block.BlockMachine.MachineType;
import mekanism.common.inventory.container.ContainerFilter;
import mekanism.common.inventory.container.ContainerNull;
import mekanism.common.miner.MItemStackFilter;
import mekanism.common.miner.MOreDictFilter;
import mekanism.common.miner.MinerFilter;
import mekanism.common.miner.ThreadMinerSearch;
import mekanism.common.miner.ThreadMinerSearch.State;
import mekanism.common.network.PacketTileEntity.TileEntityMessage;
import mekanism.common.tile.component.TileComponentUpgrade;
import mekanism.common.transporter.InvStack;
import mekanism.common.transporter.TransporterManager;
import mekanism.common.util.ChargeUtils;
import mekanism.common.util.InventoryUtils;
import mekanism.common.util.MekanismUtils;
import mekanism.common.util.MinerUtils;
import mekanism.common.util.TransporterUtils;

import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraftforge.common.util.Constants.NBT;
import net.minecraftforge.common.util.ForgeDirection;
import cpw.mods.fml.common.Optional.Interface;
import cpw.mods.fml.common.Optional.Method;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

import io.netty.buffer.ByteBuf;

import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;

@Interface(iface = "dan200.computercraft.api.peripheral.IPeripheral", modid = "ComputerCraft")
public class TileEntityDigitalMiner extends TileEntityElectricBlock implements IPeripheral, IUpgradeTile, IRedstoneControl, IActiveState, ISustainedData, IAdvancedBoundingBlock
{
  public static int[] EJECT_INV;

  public BitSet oresToMine = new BitSet();

  public HashList<MinerFilter> filters = new HashList<MinerFilter>();

  public ThreadMinerSearch searcher = new ThreadMinerSearch(this);

  public final double ENERGY_USAGE = Mekanism.digitalMinerUsage;

  public int radius;

  public boolean inverse;

  public int minY = 0;
  public int maxY = 60;

  public boolean doEject = false;
  public boolean doPull = false;

  public int delay;

  public int clientToMine;

  public ItemStack replaceStack;

  public boolean isActive;
  public boolean clientActive;

  public boolean silkTouch;

  public boolean running;

  public double prevEnergy;

  public int delayTicks;

  public boolean initCalc = false;

  public int numPowering;

  /** This machine's current RedstoneControl type. */
  public RedstoneControl controlType = RedstoneControl.DISABLED;

  public TileComponentUpgrade upgradeComponent = new TileComponentUpgrade(this, 28);

  public TileEntityDigitalMiner()
  {
    super("DigitalMiner", MachineType.DIGITAL_MINER.baseEnergy);
    inventory = new ItemStack[29];
    radius = 10;
  }

  @Override
  public void onUpdate()
  {
    super.onUpdate();

    if(getActive())
    {
      for(EntityPlayer player : (HashSet<EntityPlayer>)playersUsing.clone())
      {
        if(player.openContainer instanceof ContainerNull || player.openContainer instanceof ContainerFilter)
        {
          player.closeScreen();
        }
      }
    }

    if(!worldObj.isRemote)
    {
      if(!initCalc)
      {
        if(searcher.state == State.FINISHED)
        {
          reset();
          start();
        }

        initCalc = true;
      }

      ChargeUtils.discharge(27, this);

      if(MekanismUtils.canFunction(this) && running && getEnergy() >= getPerTick() && searcher.state == State.FINISHED && oresToMine.cardinality() > 0)
      {
        setActive(true);

        if(delay > 0)
        {
          delay--;
        }

        setEnergy(getEnergy()-getPerTick());

        if(delay == 0)
        {
          Set<Integer> toRemove = new HashSet<Integer>();

          int next = 0;

          while(true)
          {
            int index = oresToMine.nextSetBit(next);
            Coord4D coord = getCoordFromIndex(index);

            if(index == -1)
            {
              break;
            }

            if(!coord.exists(worldObj))
            {
              toRemove.add(index);
              next = index + 1;
              continue;
            }

            Block block = coord.getBlock(worldObj);
            int meta = coord.getMetadata(worldObj);

            if(block == null || coord.isAirBlock(worldObj))
            {
              toRemove.add(index);
              next = index + 1;
              continue;
            }

            boolean hasFilter = false;

            for(MinerFilter filter : filters)
            {
              if(filter.canFilter(new ItemStack(block, 1, meta)))
              {
                hasFilter = true;
                break;
              }
            }

            if(inverse ? hasFilter : !hasFilter)
            {
              toRemove.add(index);
              next = index + 1;
              continue;
            }

            List<ItemStack> drops = MinerUtils.getDrops(worldObj, coord, silkTouch);

            if(canInsert(drops))
            {
              add(drops);

              setReplace(coord);
              toRemove.add(index);

              worldObj.playAuxSFXAtEntity(null, 2001, coord.xCoord, coord.yCoord, coord.zCoord, Block.getIdFromBlock(block) + (meta << 12));

              delay = getDelay();
            }

            break;
          }

          for(Integer i : toRemove)
          {
            oresToMine.clear(i);
          }
        }
      }
      else {
        if(prevEnergy >= getEnergy())
        {
          setActive(false);
        }
      }

      if(doEject && delayTicks == 0 && getTopEject(false, null) != null && getEjectInv() != null && getEjectTile() != null)
      {
        if(getEjectInv() instanceof IInventory)
        {
          ItemStack remains = InventoryUtils.putStackInInventory((IInventory)getEjectInv(), getTopEject(false, null), ForgeDirection.getOrientation(facing).getOpposite().ordinal(), false);

          getTopEject(true, remains);
        }
        else if(getEjectInv() instanceof ILogisticalTransporter)
        {
          ItemStack rejected = TransporterUtils.insert(getEjectTile(), (ILogisticalTransporter)getEjectInv(), getTopEject(false, null), null, true, 0);

          if(TransporterManager.didEmit(getTopEject(false, null), rejected))
          {
            getTopEject(true, rejected);
          }
        }

        delayTicks = 10;
      }
      else if(delayTicks > 0)
      {
        delayTicks--;
      }

      if(playersUsing.size() > 0)
      {
        for(EntityPlayer player : playersUsing)
        {
          Mekanism.packetHandler.sendTo(new TileEntityMessage(Coord4D.get(this), getSmallPacket(new ArrayList())), (EntityPlayerMP)player);
        }
      }

      prevEnergy = getEnergy();
    }
  }

  public double getPerTick()
  {
    double ret = MekanismUtils.getEnergyPerTick(this, ENERGY_USAGE);

    if(silkTouch)
    {
      ret *= 6F;
    }

    int baseRad = Math.max(radius-10, 0);
    ret *= (1 + ((float)baseRad/22F));

    int baseHeight = Math.max((maxY-minY)-60, 0);
    ret *= (1 + ((float)baseHeight/195F));

    return ret;
  }

  public int getDelay()
  {
    return MekanismUtils.getTicks(this, 80);
  }

  public void setReplace(Coord4D obj)
  {
    ItemStack stack = getReplace();

    if(stack != null)
    {
      worldObj.setBlock(obj.xCoord, obj.yCoord, obj.zCoord, Block.getBlockFromItem(replaceStack.getItem()), replaceStack.getItemDamage(), 3);

      if(obj.getBlock(worldObj) != null && !obj.getBlock(worldObj).canBlockStay(worldObj, obj.xCoord, obj.yCoord, obj.zCoord))
      {
        obj.getBlock(worldObj).dropBlockAsItem(worldObj, obj.xCoord, obj.yCoord, obj.zCoord, obj.getMetadata(worldObj), 1);
        worldObj.setBlockToAir(obj.xCoord, obj.yCoord, obj.zCoord);
      }
    }
    else {
      worldObj.setBlockToAir(obj.xCoord, obj.yCoord, obj.zCoord);
    }
  }

  public ItemStack getReplace()
  {
    if(replaceStack == null)
    {
      return null;
    }

    for(int i = 0; i < 27; i++)
    {
      if(inventory[i] != null && inventory[i].isItemEqual(replaceStack))
      {
        inventory[i].stackSize--;

        if(inventory[i].stackSize == 0)
        {
          inventory[i] = null;
        }

        return MekanismUtils.size(replaceStack, 1);
      }
    }

    if(doPull && getPullInv() instanceof IInventory)
    {
      InvStack stack = InventoryUtils.takeDefinedItem((IInventory)getPullInv(), 1, replaceStack.copy(), 1, 1);

      if(stack != null)
      {
        stack.use();
        return MekanismUtils.size(replaceStack, 1);
      }
    }

    return null;
  }

  public ItemStack[] copy(ItemStack[] stacks)
  {
    ItemStack[] toReturn = new ItemStack[stacks.length];

    for(int i = 0; i < stacks.length; i++)
    {
      toReturn[i] = stacks[i] != null ? stacks[i].copy() : null;
    }

    return toReturn;
  }

  public ItemStack getTopEject(boolean remove, ItemStack reject)
  {
    for(int i = 27-1; i >= 0; i--)
    {
      ItemStack stack = inventory[i];

      if(stack != null)
      {
        if(replaceStack != null && replaceStack.isItemEqual(stack))
        {
          continue;
        }

        if(remove)
        {
          inventory[i] = reject;
        }

        return stack;
      }
    }

    return null;
  }

  public boolean canInsert(List<ItemStack> stacks)
  {
    if(stacks.isEmpty())
    {
      return true;
    }

    ItemStack[] testInv = copy(inventory);

    int added = 0;

    stacks:
    for(ItemStack stack : stacks)
    {
      for(int i = 0; i < 27; i++)
      {
        if(testInv[i] == null)
        {
          testInv[i] = stack;
          added++;

          continue stacks;
        }
        else if(testInv[i].isItemEqual(stack) && testInv[i].stackSize+stack.stackSize <= stack.getMaxStackSize())
        {
          testInv[i].stackSize += stack.stackSize;
          added++;

          continue stacks;
        }
      }
    }

    if(added == stacks.size())
    {
      return true;
    }

    return false;
  }

  public TileEntity getPullInv()
  {
    return Coord4D.get(this).translate(0, 2, 0).getTileEntity(worldObj);
  }

  public TileEntity getEjectInv()
  {
    ForgeDirection side = ForgeDirection.getOrientation(facing).getOpposite();

    return new Coord4D(xCoord+(side.offsetX*2), yCoord+1, zCoord+(side.offsetZ*2), worldObj.provider.dimensionId).getTileEntity(worldObj);
  }

  public void add(List<ItemStack> stacks)
  {
    if(stacks.isEmpty())
    {
      return;
    }

    stacks:
    for(ItemStack stack : stacks)
    {
      for(int i = 0; i < 27; i++)
      {
        if(inventory[i] == null)
        {
          inventory[i] = stack;

          continue stacks;
        }
        else if(inventory[i].isItemEqual(stack) && inventory[i].stackSize+stack.stackSize <= stack.getMaxStackSize())
        {
          inventory[i].stackSize += stack.stackSize;

          continue stacks;
        }
      }
    }
  }

  public void start()
  {
    if(searcher.state == State.IDLE)
    {
      searcher.start();
    }

    running = true;

    MekanismUtils.saveChunk(this);
  }

  public void stop()
  {
    if(searcher.state == State.SEARCHING)
    {
      searcher.interrupt();
      reset();

      return;
    }
    else if(searcher.state == State.FINISHED)
    {
      running = false;
    }

    MekanismUtils.saveChunk(this);
  }

  public void reset()
  {
    searcher = new ThreadMinerSearch(this);
    running = false;
    oresToMine.clear();

    MekanismUtils.saveChunk(this);
  }

  @Override
  public void openInventory()
  {
    super.openInventory();

    if(!worldObj.isRemote)
    {
      for(EntityPlayer player : playersUsing)
      {
        Mekanism.packetHandler.sendTo(new TileEntityMessage(Coord4D.get(this), getNetworkedData(new ArrayList())), (EntityPlayerMP)player);
      }
    }
  }

  @Override
  public void readFromNBT(NBTTagCompound nbtTags)
  {
    super.readFromNBT(nbtTags);

    radius = nbtTags.getInteger("radius");
    minY = nbtTags.getInteger("minY");
    maxY = nbtTags.getInteger("maxY");
    doEject = nbtTags.getBoolean("doEject");
    doPull = nbtTags.getBoolean("doPull");
    isActive = nbtTags.getBoolean("isActive");
    running = nbtTags.getBoolean("running");
    delay = nbtTags.getInteger("delay");
    silkTouch = nbtTags.getBoolean("silkTouch");
    numPowering = nbtTags.getInteger("numPowering");
    searcher.state = State.values()[nbtTags.getInteger("state")];
    controlType = RedstoneControl.values()[nbtTags.getInteger("controlType")];
    inverse = nbtTags.getBoolean("inverse");

    if(nbtTags.hasKey("replaceStack"))
    {
      replaceStack = ItemStack.loadItemStackFromNBT(nbtTags.getCompoundTag("replaceStack"));
    }

    if(nbtTags.hasKey("filters"))
    {
      NBTTagList tagList = nbtTags.getTagList("filters", NBT.TAG_COMPOUND);

      for(int i = 0; i < tagList.tagCount(); i++)
      {
        filters.add(MinerFilter.readFromNBT((NBTTagCompound)tagList.getCompoundTagAt(i)));
      }
    }
  }

  @Override
  public void writeToNBT(NBTTagCompound nbtTags)
  {
    super.writeToNBT(nbtTags);

    if(searcher.state == State.SEARCHING)
    {
      reset();
    }

    nbtTags.setInteger("radius", radius);
    nbtTags.setInteger("minY", minY);
    nbtTags.setInteger("maxY", maxY);
    nbtTags.setBoolean("doEject", doEject);
    nbtTags.setBoolean("doPull", doPull);
    nbtTags.setBoolean("isActive", isActive);
    nbtTags.setBoolean("running", running);
    nbtTags.setInteger("delay", delay);
    nbtTags.setBoolean("silkTouch", silkTouch);
    nbtTags.setInteger("numPowering", numPowering);
    nbtTags.setInteger("state", searcher.state.ordinal());
    nbtTags.setInteger("controlType", controlType.ordinal());
    nbtTags.setBoolean("inverse", inverse);

    if(replaceStack != null)
    {
      nbtTags.setTag("replaceStack", replaceStack.writeToNBT(new NBTTagCompound()));
    }

    NBTTagList filterTags = new NBTTagList();

    for(MinerFilter filter : filters)
    {
      filterTags.appendTag(filter.write(new NBTTagCompound()));
    }

    if(filterTags.tagCount() != 0)
    {
      nbtTags.setTag("filters", filterTags);
    }
  }

  @Override
  public void handlePacketData(ByteBuf dataStream)
  {
    if(!worldObj.isRemote)
    {
      int type = dataStream.readInt();

      if(type == 0)
      {
        doEject = !doEject;
      }
      else if(type == 1)
      {
        doPull = !doPull;
      }
      else if(type == 2)
      {
        boolean doNull = dataStream.readBoolean();

        if(!doNull)
        {
          replaceStack = new ItemStack(Block.getBlockById(dataStream.readInt()), 1, dataStream.readInt());
        }
        else {
          replaceStack = null;
        }
      }
      else if(type == 3)
      {
        start();
      }
      else if(type == 4)
      {
        stop();
      }
      else if(type == 5)
      {
        reset();
      }
      else if(type == 6)
      {
        radius = dataStream.readInt();
      }
      else if(type == 7)
      {
        minY = dataStream.readInt();
      }
      else if(type == 8)
      {
        maxY = dataStream.readInt();
      }
      else if(type == 9)
      {
        silkTouch = !silkTouch;
      }
      else if(type == 10)
      {
        inverse = !inverse;
      }

      for(EntityPlayer player : playersUsing)
      {
        Mekanism.packetHandler.sendTo(new TileEntityMessage(Coord4D.get(this), getGenericPacket(new ArrayList())), (EntityPlayerMP)player);
      }

      return;
    }

    super.handlePacketData(dataStream);

    int type = dataStream.readInt();

    if(type == 0)
    {
      radius = dataStream.readInt();
      minY = dataStream.readInt();
      maxY = dataStream.readInt();
      doEject = dataStream.readBoolean();
      doPull = dataStream.readBoolean();
      isActive = dataStream.readBoolean();
      running = dataStream.readBoolean();
      silkTouch = dataStream.readBoolean();
      numPowering = dataStream.readInt();
      searcher.state = State.values()[dataStream.readInt()];

      if(dataStream.readBoolean())
      {
        replaceStack = new ItemStack(Block.getBlockById(dataStream.readInt()), 1, dataStream.readInt());
      }
      else {
        replaceStack = null;
      }

      clientToMine = dataStream.readInt();
      controlType = RedstoneControl.values()[dataStream.readInt()];
      inverse = dataStream.readBoolean();

      filters.clear();

      int amount = dataStream.readInt();

      for(int i = 0; i < amount; i++)
      {
        filters.add(MinerFilter.readFromPacket(dataStream));
      }
    }
    else if(type == 1)
    {
      radius = dataStream.readInt();
      minY = dataStream.readInt();
      maxY = dataStream.readInt();
      doEject = dataStream.readBoolean();
      doPull = dataStream.readBoolean();
      isActive = dataStream.readBoolean();
      running = dataStream.readBoolean();
      silkTouch = dataStream.readBoolean();
      numPowering = dataStream.readInt();
      searcher.state = State.values()[dataStream.readInt()];

      if(dataStream.readBoolean())
      {
        replaceStack = new ItemStack(Block.getBlockById(dataStream.readInt()), 1, dataStream.readInt());
      }
      else {
        replaceStack = null;
      }

      clientToMine = dataStream.readInt();
      controlType = RedstoneControl.values()[dataStream.readInt()];
      inverse = dataStream.readBoolean();
    }
    else if(type == 2)
    {
      filters.clear();

      int amount = dataStream.readInt();

      for(int i = 0; i < amount; i++)
      {
        filters.add(MinerFilter.readFromPacket(dataStream));
      }
    }
    else if(type == 3)
    {
      isActive = dataStream.readBoolean();
      running = dataStream.readBoolean();
      clientToMine = dataStream.readInt();
    }
  }

  @Override
  public ArrayList getNetworkedData(ArrayList data)
  {
    super.getNetworkedData(data);

    data.add(0);

    data.add(radius);
    data.add(minY);
    data.add(maxY);
    data.add(doEject);
    data.add(doPull);
    data.add(isActive);
    data.add(running);
    data.add(silkTouch);
    data.add(numPowering);
    data.add(searcher.state.ordinal());

    if(replaceStack != null)
    {
      data.add(true);
      data.add(MekanismUtils.getID(replaceStack));
      data.add(replaceStack.getItemDamage());
    }
    else {
      data.add(false);
    }

    if(searcher.state == State.SEARCHING)
    {
      data.add(searcher.found);
    }
    else {
      data.add(oresToMine.cardinality());
    }

    data.add(controlType.ordinal());
    data.add(inverse);

    data.add(filters.size());

    for(MinerFilter filter : filters)
    {
      filter.write(data);
    }

    return data;
  }

  public ArrayList getSmallPacket(ArrayList data)
  {
    super.getNetworkedData(data);

    data.add(3);

    data.add(isActive);
    data.add(running);

    if(searcher.state == State.SEARCHING)
    {
      data.add(searcher.found);
    }
    else {
      data.add(oresToMine.cardinality());
    }

    return data;
  }

  public ArrayList getGenericPacket(ArrayList data)
  {
    super.getNetworkedData(data);

    data.add(1);

    data.add(radius);
    data.add(minY);
    data.add(maxY);
    data.add(doEject);
    data.add(doPull);
    data.add(isActive);
    data.add(running);
    data.add(silkTouch);
    data.add(numPowering);
    data.add(searcher.state.ordinal());

    if(replaceStack != null)
    {
      data.add(true);
      data.add(MekanismUtils.getID(replaceStack));
      data.add(replaceStack.getItemDamage());
    }
    else {
      data.add(false);
    }

    if(searcher.state == State.SEARCHING)
    {
      data.add(searcher.found);
    }
    else {
      data.add(oresToMine.cardinality());
    }

    data.add(controlType.ordinal());
    data.add(inverse);

    return data;
  }

  public ArrayList getFilterPacket(ArrayList data)
  {
    super.getNetworkedData(data);

    data.add(2);

    data.add(filters.size());

    for(MinerFilter filter : filters)
    {
      filter.write(data);
    }

    return data;
  }

  public int getTotalSize()
  {
    return getDiameter()*getDiameter()*(maxY-minY+1);
  }

  public int getDiameter()
  {
    return (radius*2)+1;
  }

  public Coord4D getStartingCoord()
  {
    return new Coord4D(xCoord-radius, minY, zCoord-radius, worldObj.provider.dimensionId);
  }

  public Coord4D getCoordFromIndex(int index)
  {
    int diameter = getDiameter();
    Coord4D start = getStartingCoord();

    int x = start.xCoord+index%diameter;
    int z = start.zCoord+(index/diameter)%diameter;
    int y = start.yCoord+(index/diameter/diameter);

    return new Coord4D(x, y, z, worldObj.provider.dimensionId);
  }

  @Override
  public double getMaxEnergy()
  {
    return MekanismUtils.getMaxEnergy(this, MAX_ELECTRICITY);
  }

  @Override
  public boolean isPowered()
  {
    return redstone || numPowering > 0;
  }

  @Override
  public RedstoneControl getControlType()
  {
    return controlType;
  }

  @Override
  public void setControlType(RedstoneControl type)
  {
    controlType = type;
    MekanismUtils.saveChunk(this);
  }

  @Override
  public TileComponentUpgrade getComponent()
  {
    return upgradeComponent;
  }

  @Override
  public int getEnergyMultiplier(Object... data)
  {
    return upgradeComponent.energyMultiplier;
  }

  @Override
  public void setEnergyMultiplier(int multiplier, Object... data)
  {
    upgradeComponent.energyMultiplier = multiplier;
    MekanismUtils.saveChunk(this);
  }

  @Override
  public int getSpeedMultiplier(Object... data)
  {
    return upgradeComponent.speedMultiplier;
  }

  @Override
  public void setSpeedMultiplier(int multiplier, Object... data)
  {
    upgradeComponent.speedMultiplier = multiplier;
    MekanismUtils.saveChunk(this);
  }

  @Override
  public boolean supportsUpgrades(Object... data)
  {
    return true;
  }

  @Override
  public void setActive(boolean active)
  {
    isActive = active;

    if(clientActive != active)
    {
      Mekanism.packetHandler.sendToReceivers(new TileEntityMessage(Coord4D.get(this), getNetworkedData(new ArrayList())), new Range4D(Coord4D.get(this)));

      clientActive = active;
    }
  }

  @Override
  public boolean getActive()
  {
    return isActive;
  }

  @Override
  public boolean renderUpdate()
  {
    return false;
  }

  @Override
  public boolean lightUpdate()
  {
    return true;
  }

  @Override
  @SideOnly(Side.CLIENT)
  public AxisAlignedBB getRenderBoundingBox()
  {
    return INFINITE_EXTENT_AABB;
  }

  @Override
  public void onPlace()
  {
    for(int x = xCoord-1; x <= xCoord+1; x++)
    {
      for(int y = yCoord; y <= yCoord+1; y++)
      {
        for(int z = zCoord-1; z <= zCoord+1; z++)
        {
          if(x == xCoord && y == yCoord && z == zCoord)
          {
            continue;
          }

          MekanismUtils.makeAdvancedBoundingBlock(worldObj, x, y, z, Coord4D.get(this));
                worldObj.func_147453_f(x, y, z, getBlockType());
        }
      }
    }
  }

  @Override
  public boolean canSetFacing(int side)
  {
    return side != 0 && side != 1;
  }

  @Override
  public void onBreak()
  {
    for(int x = xCoord-1; x <= xCoord+1; x++)
    {
      for(int y = yCoord; y <= yCoord+1; y++)
      {
        for(int z = zCoord-1; z <= zCoord+1; z++)
        {
          worldObj.setBlockToAir(x, y, z);
        }
      }
    }
  }

  @Override
  public int[] getAccessibleSlotsFromSide(int side)
  {
    return InventoryUtils.EMPTY;
  }

  public TileEntity getEjectTile()
  {
    ForgeDirection side = ForgeDirection.getOrientation(facing).getOpposite();
    return new Coord4D(xCoord+side.offsetX, yCoord+1, zCoord+side.offsetZ, worldObj.provider.dimensionId).getTileEntity(worldObj);
  }

  @Override
  public int[] getBoundSlots(Coord4D location, int side)
  {
    ForgeDirection dir = ForgeDirection.getOrientation(facing).getOpposite();

    Coord4D eject = Coord4D.get(this).translate(dir.offsetX, 1, dir.offsetZ);
    Coord4D pull = Coord4D.get(this).translate(0, 1, 0);

    if((location.equals(eject) && side == dir.ordinal()) || (location.equals(pull) && side == 1))
    {
      if(EJECT_INV == null)
      {
        EJECT_INV = new int[27];

        for(int i = 0; i < EJECT_INV.length; i++)
        {
          EJECT_INV[i] = i;
        }
      }

      return EJECT_INV;
    }

    return InventoryUtils.EMPTY;
  }

  @Override
  public boolean canBoundInsert(Coord4D location, int i, ItemStack itemstack)
  {
    ForgeDirection side = ForgeDirection.getOrientation(facing).getOpposite();

    Coord4D eject = Coord4D.get(this).translate(side.offsetX, 1, side.offsetZ);
    Coord4D pull = Coord4D.get(this).translate(0, 1, 0);

    if(location.equals(eject))
    {
      return false;
    }
    else if(location.equals(pull))
    {
      if(itemstack != null && replaceStack != null && itemstack.isItemEqual(replaceStack))
      {
        return true;
      }
    }

    return false;
  }

  @Override
  public boolean canBoundExtract(Coord4D location, int i, ItemStack itemstack, int j)
  {
    ForgeDirection side = ForgeDirection.getOrientation(facing).getOpposite();

    Coord4D eject = new Coord4D(xCoord+side.offsetX, yCoord+1, zCoord+side.offsetZ, worldObj.provider.dimensionId);
    Coord4D pull = new Coord4D(xCoord, yCoord+1, zCoord, worldObj.provider.dimensionId);

    if(location.equals(eject))
    {
      if(itemstack != null && replaceStack != null && itemstack.isItemEqual(replaceStack))
      {
        return false;
      }

      return true;
    }
    else if(location.equals(pull))
    {
      return false;
    }

    return false;
  }

  @Override
  public void onPower()
  {
    numPowering++;
  }

  @Override
  public void onNoPower()
  {
    numPowering--;
  }

  @Override
  @Method(modid = "ComputerCraft")
  public String getType()
  {
    return getInventoryName();
  }

  public String[] names = {"setRadius", "setMin", "setMax", "setReplace", "addFilter", "removeFilter", "addOreFilter", "removeOreFilter", "reset", "start", "stop"};

  @Override
  @Method(modid = "ComputerCraft")
  public String[] getMethodNames()
  {
    return names;
  }

  @Override
  @Method(modid = "ComputerCraft")
  public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) throws LuaException, InterruptedException
  {
    if(arguments.length > 0)
    {
      int num = 0;

      if(arguments[0] instanceof Double)
      {
        num = ((Double)arguments[0]).intValue();
      }
      else if(arguments[0] instanceof String && (method != 6 && method != 7))
      {
        num = Integer.parseInt((String)arguments[0]);
      }

      if(num != 0)
      {
        if(method == 0)
        {
          radius = num;
        }
        else if(method == 1)
        {
          minY = num;
        }
        else if(method == 2)
        {
          maxY = num;
        }
        else if(method == 3)
        {
          int meta = 0;

          if(arguments.length > 1)
          {
            if(arguments[1] instanceof Double)
            {
              num = ((Double)arguments[1]).intValue();
            }
            else if(arguments[1] instanceof String)
            {
              meta = Integer.parseInt((String)arguments[1]);
            }
          }

          replaceStack = new ItemStack(Item.getItemById(num), 1, meta);
        }
        else if(method == 4)
        {
          int meta = 0;

          if(arguments.length > 1)
          {
            if(arguments[1] instanceof Double)
            {
              meta = ((Double)arguments[1]).intValue();
            }
            else if(arguments[1] instanceof String)
            {
              meta = Integer.parseInt((String)arguments[1]);
            }
          }

          filters.add(new MItemStackFilter(new ItemStack(Item.getItemById(num), 1, meta)));
        }
        else if(method == 5)
        {
          Iterator<MinerFilter> iter = filters.iterator();

          while(iter.hasNext())
          {
            MinerFilter filter = iter.next();

            if(filter instanceof MItemStackFilter)
            {
              if(MekanismUtils.getID(((MItemStackFilter)filter).itemType) == num)
              {
                iter.remove();
              }
            }
          }
        }
        else if(method == 6)
        {
          String ore = (String)arguments[0];
          MOreDictFilter filter = new MOreDictFilter();

          filter.oreDictName = ore;
          filters.add(filter);
        }
        else if(method == 7)
        {
          String ore = (String)arguments[0];
          Iterator<MinerFilter> iter = filters.iterator();

          while(iter.hasNext())
          {
            MinerFilter filter = iter.next();

            if(filter instanceof MOreDictFilter)
            {
              if(((MOreDictFilter)filter).oreDictName == ore)
              {
                iter.remove();
              }
            }
          }
        }
        else if(method == 8)
        {
          reset();
        }
        else if(method == 9)
        {
          start();
        }
        else if(method == 10)
        {
          stop();
        }
      }
    }

    for(EntityPlayer player : playersUsing)
    {
      Mekanism.packetHandler.sendTo(new TileEntityMessage(Coord4D.get(this), getGenericPacket(new ArrayList())), (EntityPlayerMP)player);
    }

    return null;
  }

  @Override
  @Method(modid = "ComputerCraft")
  public boolean equals(IPeripheral other)
  {
    return this == other;
  }

  @Override
  @Method(modid = "ComputerCraft")
  public void attach(IComputerAccess computer) {}

  @Override
  @Method(modid = "ComputerCraft")
  public void detach(IComputerAccess computer) {}

  @Override
  public NBTTagCompound getFilterData(NBTTagCompound nbtTags)
  {
    nbtTags.setInteger("radius", radius);
    nbtTags.setInteger("minY", minY);
    nbtTags.setInteger("maxY", maxY);
    nbtTags.setBoolean("doEject", doEject);
    nbtTags.setBoolean("doPull", doPull);
    nbtTags.setBoolean("silkTouch", silkTouch);
    nbtTags.setInteger("controlType", controlType.ordinal());
    nbtTags.setBoolean("inverse", inverse);

    if(replaceStack != null)
    {
      nbtTags.setTag("replaceStack", replaceStack.writeToNBT(new NBTTagCompound()));
    }

    NBTTagList filterTags = new NBTTagList();

    for(MinerFilter filter : filters)
    {
      filterTags.appendTag(filter.write(new NBTTagCompound()));
    }

    if(filterTags.tagCount() != 0)
    {
      nbtTags.setTag("filters", filterTags);
    }
   
    return nbtTags;
  }

  @Override
  public void setFilterData(NBTTagCompound nbtTags)
  {
    radius = nbtTags.getInteger("radius");
    minY = nbtTags.getInteger("minY");
    maxY = nbtTags.getInteger("maxY");
    doEject = nbtTags.getBoolean("doEject");
    doPull = nbtTags.getBoolean("doPull");
    silkTouch = nbtTags.getBoolean("silkTouch");
    controlType = RedstoneControl.values()[nbtTags.getInteger("controlType")];
    inverse = nbtTags.getBoolean("inverse");

    if(nbtTags.hasKey("replaceStack"))
    {
      replaceStack = ItemStack.loadItemStackFromNBT(nbtTags.getCompoundTag("replaceStack"));
    }

    if(nbtTags.hasKey("filters"))
    {
      NBTTagList tagList = nbtTags.getTagList("filters", NBT.TAG_COMPOUND);

      for(int i = 0; i < tagList.tagCount(); i++)
      {
        filters.add(MinerFilter.readFromNBT((NBTTagCompound)tagList.getCompoundTagAt(i)));
      }
    }
  }

  @Override
  public String getDataType()
  {
    return "tooltip.filterCard.digitalMiner";
  }

  @Override
  public void writeSustainedData(ItemStack itemStack)
  {
    itemStack.stackTagCompound.setBoolean("hasMinerConfig", true);

    itemStack.stackTagCompound.setInteger("radius", radius);
    itemStack.stackTagCompound.setInteger("minY", minY);
    itemStack.stackTagCompound.setInteger("maxY", maxY);
    itemStack.stackTagCompound.setBoolean("doEject", doEject);
    itemStack.stackTagCompound.setBoolean("doPull", doPull);
    itemStack.stackTagCompound.setBoolean("silkTouch", silkTouch);
    itemStack.stackTagCompound.setBoolean("inverse", inverse);

    if(replaceStack != null)
    {
      itemStack.stackTagCompound.setTag("replaceStack", replaceStack.writeToNBT(new NBTTagCompound()));
    }

    NBTTagList filterTags = new NBTTagList();

    for(MinerFilter filter : filters)
    {
      filterTags.appendTag(filter.write(new NBTTagCompound()));
    }

    if(filterTags.tagCount() != 0)
    {
      itemStack.stackTagCompound.setTag("filters", filterTags);
    }
  }

  @Override
  public void readSustainedData(ItemStack itemStack)
  {
    if(itemStack.stackTagCompound.hasKey("hasMinerConfig"))
    {
      radius = itemStack.stackTagCompound.getInteger("radius");
      minY = itemStack.stackTagCompound.getInteger("minY");
      maxY = itemStack.stackTagCompound.getInteger("maxY");
      doEject = itemStack.stackTagCompound.getBoolean("doEject");
      doPull = itemStack.stackTagCompound.getBoolean("doPull");
      silkTouch = itemStack.stackTagCompound.getBoolean("silkTouch");
      inverse = itemStack.stackTagCompound.getBoolean("inverse");

      if(itemStack.stackTagCompound.hasKey("replaceStack"))
      {
        replaceStack = ItemStack.loadItemStackFromNBT(itemStack.stackTagCompound.getCompoundTag("replaceStack"));
      }

      if(itemStack.stackTagCompound.hasKey("filters"))
      {
        NBTTagList tagList = itemStack.stackTagCompound.getTagList("filters", NBT.TAG_COMPOUND);

        for(int i = 0; i < tagList.tagCount(); i++)
        {
          filters.add(MinerFilter.readFromNBT((NBTTagCompound)tagList.getCompoundTagAt(i)));
        }
      }
    }
  }
}
TOP

Related Classes of mekanism.common.tile.TileEntityDigitalMiner

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.