blob: 941948c0004ba75031c666225f130b1d69cac426 [file] [log] [blame] [raw]
package mekanism.common.tile;
import cpw.mods.fml.common.Optional.Method;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import io.netty.buffer.ByteBuf;
import mekanism.api.Chunk3D;
import mekanism.api.Coord4D;
import mekanism.api.MekanismConfig.usage;
import mekanism.api.Range4D;
import mekanism.common.HashList;
import mekanism.common.Mekanism;
import mekanism.common.Upgrade;
import mekanism.common.base.*;
import mekanism.common.block.BlockMachine.MachineType;
import mekanism.common.content.miner.MItemStackFilter;
import mekanism.common.content.miner.MOreDictFilter;
import mekanism.common.content.miner.MinerFilter;
import mekanism.common.content.miner.ThreadMinerSearch;
import mekanism.common.content.miner.ThreadMinerSearch.State;
import mekanism.common.content.transporter.InvStack;
import mekanism.common.content.transporter.TransporterManager;
import mekanism.common.inventory.container.ContainerFilter;
import mekanism.common.inventory.container.ContainerNull;
import mekanism.common.network.PacketTileEntity.TileEntityMessage;
import mekanism.common.tile.component.TileComponentUpgrade;
import mekanism.common.util.*;
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.minecraft.world.WorldServer;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.util.Constants.NBT;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.event.world.BlockEvent;
import java.util.*;
public class TileEntityDigitalMiner extends TileEntityElectricBlock implements IUpgradeTile, IRedstoneControl, IActiveState, ISustainedData, IAdvancedBoundingBlock
{
public static int[] EJECT_INV;
public Map<Chunk3D, BitSet> oresToMine = new HashMap<Chunk3D, BitSet>();
public Map<Integer, MinerFilter> replaceMap = new HashMap<Integer, MinerFilter>();
public HashList<MinerFilter> filters = new HashList<MinerFilter>();
public ThreadMinerSearch searcher = new ThreadMinerSearch(this);
public final double BASE_ENERGY_USAGE = usage.digitalMinerUsage;
public double energyUsage = usage.digitalMinerUsage;
public int radius;
public boolean inverse;
public int minY = 0;
public int maxY = 60;
public boolean doEject = false;
public boolean doPull = false;
public ItemStack missingStack = null;
public int BASE_DELAY = 80;
public int delay;
public int delayLength = BASE_DELAY;
public int clientToMine;
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;
public boolean clientRendering = false;
/** 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)
{
boolean prevRunning = running;
reset();
start();
running = prevRunning;
}
initCalc = true;
}
ChargeUtils.discharge(27, this);
if(MekanismUtils.canFunction(this) && running && getEnergy() >= getPerTick() && searcher.state == State.FINISHED && oresToMine.size() > 0)
{
setActive(true);
if(delay > 0)
{
delay--;
}
setEnergy(getEnergy()-getPerTick());
if(delay == 0)
{
Set<Chunk3D> toRemove = new HashSet<Chunk3D>();
boolean did = false;
for(Chunk3D chunk : oresToMine.keySet())
{
BitSet set = oresToMine.get(chunk);
int next = 0;
while(true)
{
int index = set.nextSetBit(next);
Coord4D coord = getCoordFromIndex(index);
if(index == -1)
{
toRemove.add(chunk);
break;
}
if(!coord.exists(worldObj))
{
set.clear(index);
if(set.cardinality() == 0)
{
toRemove.add(chunk);
}
next = index + 1;
continue;
}
Block block = coord.getBlock(worldObj);
int meta = coord.getMetadata(worldObj);
if(block == null || coord.isAirBlock(worldObj))
{
set.clear(index);
if(set.cardinality() == 0)
{
toRemove.add(chunk);
}
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)
{
set.clear(index);
if(set.cardinality() == 0)
{
toRemove.add(chunk);
break;
}
next = index + 1;
continue;
}
List<ItemStack> drops = MinerUtils.getDrops(worldObj, coord, silkTouch);
if(canInsert(drops) && setReplace(coord, index))
{
did = true;
add(drops);
set.clear(index);
if(set.cardinality() == 0)
{
toRemove.add(chunk);
}
worldObj.playAuxSFXAtEntity(null, 2001, coord.xCoord, coord.yCoord, coord.zCoord, Block.getIdFromBlock(block) + (meta << 12));
missingStack = null;
}
break;
}
if(did)
{
break;
}
}
for(Chunk3D chunk : toRemove)
{
oresToMine.remove(chunk);
}
delay = getDelay();
}
}
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 ITransporterTile)
{
ItemStack rejected = TransporterUtils.insert(getEjectTile(), ((ITransporterTile)getEjectInv()).getTransmitter(), 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 = energyUsage;
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 delayLength;
}
/*
* returns false if unsuccessful
*/
public boolean setReplace(Coord4D obj, int index)
{
Block block = obj.getBlock(worldObj);
int meta = obj.getMetadata(worldObj);
EntityPlayer dummy = Mekanism.proxy.getDummyPlayer((WorldServer)worldObj, obj.xCoord, obj.yCoord, obj.zCoord).get();
BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(obj.xCoord, obj.yCoord, obj.zCoord, worldObj, block, meta, dummy);
MinecraftForge.EVENT_BUS.post(event);
if(!event.isCanceled())
{
ItemStack stack = getReplace(index);
if(stack != null)
{
worldObj.setBlock(obj.xCoord, obj.yCoord, obj.zCoord, Block.getBlockFromItem(stack.getItem()), stack.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);
}
return true;
}
else {
MinerFilter filter = replaceMap.get(index);
if(filter == null || (filter.replaceStack == null || !filter.requireStack))
{
worldObj.setBlockToAir(obj.xCoord, obj.yCoord, obj.zCoord);
return true;
}
missingStack = filter.replaceStack;
return false;
}
}
return false;
}
public ItemStack getReplace(int index)
{
MinerFilter filter = replaceMap.get(index);
if(filter == null || filter.replaceStack == null)
{
return null;
}
for(int i = 0; i < 27; i++)
{
if(inventory[i] != null && inventory[i].isItemEqual(filter.replaceStack))
{
inventory[i].stackSize--;
if(inventory[i].stackSize == 0)
{
inventory[i] = null;
}
return MekanismUtils.size(filter.replaceStack, 1);
}
}
if(doPull && getPullInv() instanceof IInventory)
{
InvStack stack = InventoryUtils.takeDefinedItem((IInventory)getPullInv(), 1, filter.replaceStack.copy(), 1, 1);
if(stack != null)
{
stack.use();
return MekanismUtils.size(filter.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(isReplaceStack(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)
{
if(stack == null || stack.getItem() == null)
{
continue;
}
for(int i = 0; i < 27; i++)
{
if(testInv[i] != null && testInv[i].getItem() == null)
{
testInv[i] = null;
}
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();
replaceMap.clear();
missingStack = null;
MekanismUtils.saveChunk(this);
}
public boolean isReplaceStack(ItemStack stack)
{
for(MinerFilter filter : filters)
{
if(filter.replaceStack != null && filter.replaceStack.isItemEqual(stack))
{
return true;
}
}
return false;
}
public int getSize()
{
int size = 0;
for(Chunk3D chunk : oresToMine.keySet())
{
size += oresToMine.get(chunk).cardinality();
}
return size;
}
@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("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);
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)
{
//Unneeded at the moment
}
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;
}
else if(type == 11)
{
// Move filter up
int filterIndex = dataStream.readInt();
filters.swap( filterIndex, filterIndex - 1 );
openInventory();
}
else if(type == 12)
{
// Move filter down
int filterIndex = dataStream.readInt();
filters.swap( filterIndex, filterIndex + 1 );
openInventory();
}
MekanismUtils.saveChunk(this);
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()];
clientToMine = dataStream.readInt();
controlType = RedstoneControl.values()[dataStream.readInt()];
inverse = dataStream.readBoolean();
if(dataStream.readBoolean())
{
missingStack = new ItemStack(Item.getItemById(dataStream.readInt()), 1, dataStream.readInt());
}
else {
missingStack = null;
}
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()];
clientToMine = dataStream.readInt();
controlType = RedstoneControl.values()[dataStream.readInt()];
inverse = dataStream.readBoolean();
if(dataStream.readBoolean())
{
missingStack = new ItemStack(Item.getItemById(dataStream.readInt()), 1, dataStream.readInt());
}
else {
missingStack = null;
}
}
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();
if(dataStream.readBoolean())
{
missingStack = new ItemStack(Item.getItemById(dataStream.readInt()), 1, dataStream.readInt());
}
else {
missingStack = null;
}
}
}
@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(searcher.state == State.SEARCHING)
{
data.add(searcher.found);
}
else {
data.add(getSize());
}
data.add(controlType.ordinal());
data.add(inverse);
if(missingStack != null)
{
data.add(true);
data.add(MekanismUtils.getID(missingStack));
data.add(missingStack.getItemDamage());
}
else {
data.add(false);
}
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(getSize());
}
if(missingStack != null)
{
data.add(true);
data.add(MekanismUtils.getID(missingStack));
data.add(missingStack.getItemDamage());
}
else {
data.add(false);
}
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(searcher.state == State.SEARCHING)
{
data.add(searcher.found);
}
else {
data.add(getSize());
}
data.add(controlType.ordinal());
data.add(inverse);
if(missingStack != null)
{
data.add(true);
data.add(MekanismUtils.getID(missingStack));
data.add(missingStack.getItemDamage());
}
else {
data.add(false);
}
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 boolean isPowered()
{
return redstone || numPowering > 0;
}
@Override
public boolean canPulse()
{
return false;
}
@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 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 && isReplaceStack(itemstack))
{
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 && isReplaceStack(itemstack))
{
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();
}
@Override
@Method(modid = "ComputerCraft")
public String[] getMethodNames()
{
return getMethods();
}
@Override
@Method(modid = "ComputerCraft")
public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) throws LuaException, InterruptedException
{
try {
return invoke(method, arguments);
} catch(NoSuchMethodException e) {
return new Object[] {"Unknown command."};
} finally {
return new Object[] {"Error."};
}
}
public String[] methods = {"setRadius", "setMin", "setMax", "addFilter", "removeFilter", "addOreFilter", "removeOreFilter", "reset", "start", "stop"};
@Override
public String[] getMethods()
{
return methods;
}
@Override
public Object[] invoke(int method, Object[] arguments) throws Exception
{
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)
{
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 == 4)
{
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 == 5)
{
String ore = (String)arguments[0];
MOreDictFilter filter = new MOreDictFilter();
filter.oreDictName = ore;
filters.add(filter);
}
else if(method == 6)
{
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 == 7)
{
reset();
}
else if(method == 8)
{
start();
}
else if(method == 9)
{
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);
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("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";
}
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);
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("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)));
}
}
}
}
@Override
public void recalculateUpgradables(Upgrade upgrade)
{
super.recalculateUpgradables(upgrade);
switch(upgrade)
{
case SPEED:
delayLength = MekanismUtils.getTicks(this, BASE_DELAY);
case ENERGY:
energyUsage = MekanismUtils.getEnergyPerTick(this, BASE_ENERGY_USAGE);
maxEnergy = MekanismUtils.getMaxEnergy(this, BASE_MAX_ENERGY);
default:
break;
}
}
}