blob: 4ef44e9366b88159d11df3df90a5dd5524534531 [file] [log] [blame] [raw]
package mekanism.common.tile;
import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
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.IActiveState;
import mekanism.common.base.IAdvancedBoundingBlock;
import mekanism.common.base.IRedstoneControl;
import mekanism.common.base.ISustainedData;
import mekanism.common.base.ITransporterTile;
import mekanism.common.base.IUpgradeTile;
import mekanism.common.block.states.BlockStateMachine;
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.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.block.BlockBush;
import net.minecraft.block.state.IBlockState;
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.util.BlockPos;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.util.Constants.NBT;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
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", BlockStateMachine.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;
}
IBlockState state = coord.getBlockState(worldObj);
Block block = state.getBlock();
int meta = block.getMetaFromState(state);
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)
{
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, 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), facing.getOpposite(), 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)
{
IBlockState state = obj.getBlockState(worldObj);
Block block = state.getBlock();
EntityPlayer dummy = Mekanism.proxy.getDummyPlayer((WorldServer)worldObj, obj.getX(), obj.getY(), obj.getZ()).get();
BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(worldObj, obj, state, dummy);
MinecraftForge.EVENT_BUS.post(event);
if(!event.isCanceled())
{
ItemStack stack = getReplace(index);
if(stack != null)
{
worldObj.setBlockState(obj, Block.getBlockFromItem(stack.getItem()).getStateFromMeta(stack.getItemDamage()), 3);
IBlockState s = obj.getBlockState(worldObj);
if(s.getBlock() instanceof BlockBush && !((BlockBush)s.getBlock()).canBlockStay(worldObj, obj, s))
{
s.getBlock().dropBlockAsItem(worldObj, obj, s, 1);
worldObj.setBlockToAir(obj);
}
return true;
}
else {
MinerFilter filter = replaceMap.get(index);
if(filter == null || (filter.replaceStack == null || !filter.requireStack))
{
worldObj.setBlockToAir(obj);
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(), EnumFacing.UP, 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).add(0, 2, 0).getTileEntity(worldObj);
}
public TileEntity getEjectInv()
{
EnumFacing side = facing.getOpposite();
return worldObj.getTileEntity(getPos().up().offset(side, 2));
}
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(EntityPlayer player)
{
super.openInventory(player);
if(!worldObj.isRemote)
{
for(EntityPlayer play : playersUsing)
{
Mekanism.packetHandler.sendTo(new TileEntityMessage(Coord4D.get(this), getNetworkedData(new ArrayList())), (EntityPlayerMP)play);
}
}
}
@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(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();
switch(type)
{
case 0:
doEject = !doEject;
break;
case 1:
doPull = !doPull;
break;
case 3:
start();
break;
case 4:
stop();
break;
case 5:
reset();
break;
case 6:
radius = dataStream.readInt();
break;
case 7:
minY = dataStream.readInt();
break;
case 8:
maxY = dataStream.readInt();
break;
case 9:
silkTouch = !silkTouch;
break;
case 10:
inverse = !inverse;
break;
case 11:
{
// Move filter up
int filterIndex = dataStream.readInt();
filters.swap(filterIndex, filterIndex - 1);
for(EntityPlayer player : playersUsing) openInventory(player); //TODO ?
break;
}
case 12:
{
// Move filter down
int filterIndex = dataStream.readInt();
filters.swap(filterIndex, filterIndex + 1);
for(EntityPlayer player : playersUsing) openInventory(player); //TODO ?
break;
}
}
MekanismUtils.saveChunk(this);
for(EntityPlayer player : playersUsing)
{
Mekanism.packetHandler.sendTo(new TileEntityMessage(Coord4D.get(this), getGenericPacket(new ArrayList<Object>())), (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();
clientActive = 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();
clientActive = 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)
{
clientActive = dataStream.readBoolean();
running = dataStream.readBoolean();
clientToMine = dataStream.readInt();
if(dataStream.readBoolean())
{
missingStack = new ItemStack(Item.getItemById(dataStream.readInt()), 1, dataStream.readInt());
}
else {
missingStack = null;
}
}
if(clientActive != isActive)
{
isActive = clientActive;
MekanismUtils.updateBlock(worldObj, getPos());
}
}
@Override
public ArrayList<Object> getNetworkedData(ArrayList<Object> 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<Object> 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<Object> getGenericPacket(ArrayList<Object> 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<Object> 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(getPos().getX()-radius, minY, getPos().getZ()-radius, worldObj.provider.getDimensionId());
}
public Coord4D getCoordFromIndex(int index)
{
int diameter = getDiameter();
Coord4D start = getStartingCoord();
int x = start.getX()+index%diameter;
int y = start.getY()+(index/diameter/diameter);
int z = start.getZ()+(index/diameter)%diameter;
return new Coord4D(x, y, z, worldObj.provider.getDimensionId());
}
@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<Object>())), 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 = -1; x <= +1; x++)
{
for(int y = 0; y <= +1; y++)
{
for(int z = -1; z <= +1; z++)
{
if(x == 0 && y == 0 && z == 0)
{
continue;
}
BlockPos pos1 = getPos().add(x, y,z);
MekanismUtils.makeAdvancedBoundingBlock(worldObj, pos1, Coord4D.get(this));
worldObj.notifyNeighborsOfStateChange(pos1, getBlockType());
}
}
}
}
@Override
public boolean canSetFacing(int side)
{
return side != 0 && side != 1;
}
@Override
public void onBreak()
{
for(int x = -1; x <= +1; x++)
{
for(int y = 0; y <= +1; y++)
{
for(int z = -1; z <= +1; z++)
{
worldObj.setBlockToAir(getPos().add(x, y, z));
}
}
}
}
@Override
public int[] getSlotsForFace(EnumFacing side)
{
return InventoryUtils.EMPTY;
}
public TileEntity getEjectTile()
{
EnumFacing side = facing.getOpposite();
return worldObj.getTileEntity(getPos().up().offset(side));
}
@Override
public int[] getBoundSlots(Coord4D location, EnumFacing side)
{
EnumFacing dir = facing.getOpposite();
BlockPos pull = getPos().up();
BlockPos eject = pull.offset(dir);
if((location.equals(eject) && side == dir) || (location.equals(pull) && side == EnumFacing.UP))
{
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)
{
EnumFacing side = facing.getOpposite();
BlockPos pull = getPos().up();
BlockPos eject = pull.offset(side);
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, EnumFacing dir)
{
EnumFacing side = facing.getOpposite();
BlockPos pull = getPos().up();
BlockPos eject = pull.offset(side);
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--;
}
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.equals(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<Object>())), (EntityPlayerMP)player);
}
return null;
}
@Override
public NBTTagCompound getConfigurationData(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.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 setConfigurationData(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");
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(tagList.getCompoundTagAt(i)));
}
}
}
@Override
public String getDataType()
{
return getBlockType().getUnlocalizedName() + "." + fullName + ".name";
}
public void writeSustainedData(ItemStack itemStack)
{
itemStack.getTagCompound().setBoolean("hasMinerConfig", true);
itemStack.getTagCompound().setInteger("radius", radius);
itemStack.getTagCompound().setInteger("minY", minY);
itemStack.getTagCompound().setInteger("maxY", maxY);
itemStack.getTagCompound().setBoolean("doEject", doEject);
itemStack.getTagCompound().setBoolean("doPull", doPull);
itemStack.getTagCompound().setBoolean("silkTouch", silkTouch);
itemStack.getTagCompound().setBoolean("inverse", inverse);
NBTTagList filterTags = new NBTTagList();
for(MinerFilter filter : filters)
{
filterTags.appendTag(filter.write(new NBTTagCompound()));
}
if(filterTags.tagCount() != 0)
{
itemStack.getTagCompound().setTag("filters", filterTags);
}
}
@Override
public void readSustainedData(ItemStack itemStack)
{
if(itemStack.getTagCompound().hasKey("hasMinerConfig"))
{
radius = itemStack.getTagCompound().getInteger("radius");
minY = itemStack.getTagCompound().getInteger("minY");
maxY = itemStack.getTagCompound().getInteger("maxY");
doEject = itemStack.getTagCompound().getBoolean("doEject");
doPull = itemStack.getTagCompound().getBoolean("doPull");
silkTouch = itemStack.getTagCompound().getBoolean("silkTouch");
inverse = itemStack.getTagCompound().getBoolean("inverse");
if(itemStack.getTagCompound().hasKey("filters"))
{
NBTTagList tagList = itemStack.getTagCompound().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;
}
}
}