// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) braces deadcode fieldsfirst

package net.minecraft.src;

import java.util.List;
import java.util.Random;

// Referenced classes of package net.minecraft.src:
// Entity, DataWatcher, World, Block,
// Item, AxisAlignedBB, Material, MathHelper,
// EntityPlayer, DamageSource, NBTTagCompound

public class PCmo_EntityMiner extends Entity implements IInventory {

	private double velocityX;
	private double velocityY;
	private double velocityZ;

	public PCmo_EntityMiner(World world) {
		super(world);
		preventEntitySpawning = true;
		setSize(1.3F, 1.4F);
		yOffset = 0F;
		dummyPlayer = new PC_FakePlayer(world);
		entityCollisionReduction = 1.0F;
		stepHeight = 0.6F;
		isImmuneToFire = true;
	}

	public PCmo_EntityMiner(World world, double d, double d1, double d2) {
		this(world);
		setPosition(d, d1 + yOffset, d2);
		motionX = 0.0D;
		motionY = 0.0D;
		motionZ = 0.0D;
		prevPosX = d;
		prevPosY = d1;
		prevPosZ = d2;

		targetX = (int) d;
		targetZ = (int) d2;
	}

	@Override
	protected boolean canTriggerWalking() {
		return false;
	}

	@Override
	protected void entityInit() {
		dataWatcher.addObject(17, new Integer(0));
		dataWatcher.addObject(18, new Integer(1));
		dataWatcher.addObject(19, new Integer(0));
	}

	@Override
	public AxisAlignedBB getCollisionBox(Entity entity) {
		if (entity instanceof EntityItem || entity instanceof EntityXPOrb) { return null; }
		return entity.boundingBox;
	}

	@Override
	public AxisAlignedBB getBoundingBox() {
		return boundingBox;
	}

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

	@Override
	public double getMountedYOffset() {
		return 1D;
	}

	// returns true if in water. Not moved by water.
	@Override
	public boolean handleWaterMovement() {
		return worldObj.isMaterialInBB(boundingBox.expand(-0.10000000149011612D, -0.40000000596046448D, -0.10000000149011612D),
				Material.water);
	}

	@Override
	public boolean attackEntityFrom(DamageSource damagesource, int i) {
		if (damagesource != DamageSource.outOfWorld
				&& (worldObj.isRemote || isDead || (damagesource.getSourceOfDamage() == null && damagesource != DamageSource.explosion))) { return true; }
		setForwardDirection(-getForwardDirection());
		setTimeSinceHit(10);
		setDamageTaken(getDamageTaken() + i * 7);
		setBeenAttacked();
		if (getDamageTaken() > 40) {
			if (riddenByEntity != null) {
				riddenByEntity.mountEntity(this); // unmount
			}

			turnIntoBlocks();
		}
		return true;
	}

	@Override
	public void performHurtAnimation() {
		setForwardDirection(-getForwardDirection());
		setTimeSinceHit(10);
		setDamageTaken(getDamageTaken() * 11);
	}

	@Override
	public boolean canBeCollidedWith() {
		return !isDead;
	}

	@Override
	public void setPositionAndRotation2(double d, double d1, double d2, float f, float f1, int i) {
		motionX = velocityX;
		motionY = velocityY;
		motionZ = velocityZ;
	}

	@Override
	public void setVelocity(double d, double d1, double d2) {
		motionX = d;
		motionY = d1;
		motionZ = d2;
	}

	@Override
	public float getShadowSize() {
		return 1.0F;
	}

	// === CODE UTILS ===

	private Random rand = new Random();

	private EntityPlayer dummyPlayer;
	public String commandList = "";
	public int currentCommand = -1;
	private int stepCounter = 0;

	public String commandListSaved = "";
	public String program = "";
	public boolean paused = false;
	public boolean keyboard = false;
	public boolean programmingGuiOpen = false;

	public byte DESTROY = 0;
	public static final byte COBBLE = 1, DIRT = 1 << 1, GRAVEL = 1 << 2;
	public boolean keepAllFuel = false;
	public boolean torchesOnlyOnFloor = false;
	public boolean compressBlocks = false;

	private int realCommand = -1;

	// temporary status flags
	private boolean upStepLaid = false;
	private boolean bridgeDone = false;

	private int targetX, targetZ;
	private int rotationRemaining = 0;

	public int level = 1;

	private static final double[] MOTION_SPEED = { 0.02D, 0.03D, 0.04D, 0.05D, 0.06D, 0.07D, 0.095D, 0.12D };
	public boolean building = false; // flag which disables inventory checking.
	public boolean miningEnabled = true;
	public boolean bridgeEnabled = false;
	public boolean lavaFillingEnabled = true;
	public boolean waterFillingEnabled = false;

	private int fuelBuffer = 0;
	private int waitingForFuel = 0;
	private int fuelAllocated = 0;

	// front 4, bottom 2, inside 8
	private int[] mineCounter = { -1, -1, -1, -1, /* under */0, 0, /* above */0, 0, /* top */0, 0, 0, 0 };

	// effect counters
	private int miningTickCounter = 0;

	private boolean destroyStack(ItemStack stack) {
		if (stack == null) { return true; }
		if (stack.itemID == Block.cobblestone.blockID) { return (DESTROY & COBBLE) != 0; }
		if (stack.itemID == Block.dirt.blockID) { return (DESTROY & DIRT) != 0; }
		if (stack.itemID == Block.gravel.blockID) { return (DESTROY & GRAVEL) != 0; }
		return false;
	}

	public void setDestroyFlags(byte flags) {
		DESTROY = flags;
	}

	public byte getDestroyFlags() {
		return DESTROY;
	}

	public void resetEverything() {
		// miningEnabled = true;
		// bridgeEnabled = false;
		motionX = motionZ = 0;
		commandList = "";
		commandListSaved = "";
		currentCommand = -1;
		alignToBlocks();
		paused = false;
		resetStatus();
	}

	public void pauseProgram() {
		if (paused) { return; }

		// pack last instruction into saved codebuffer
		commandListSaved = new String(commandList);
		String instruction = Character.toString(PCmo_Command.getCharFromInt(currentCommand));
		if (stepCounter > 0 && PCmo_Command.isCommandMove(currentCommand)) {
			instruction = (currentCommand == PCmo_Command.FORWARD ? "" : "-") + Integer.toString(stepCounter);
		} else if (instruction.equals("?")) {
			instruction = "";
		}

		commandListSaved = instruction + " " + commandListSaved;
		commandList = "";

		resetStatus();
		paused = true;
	}

	public void resumeProgram() {
		if (!paused) { return; }

		resetStatus();
		commandList = new String(commandListSaved.trim());
		commandListSaved = "";

		paused = false;
	}

	public void runNewProgram() throws PCmo_CommandException {
		String parsed = PCmo_Command.parseCode(program);

		keyboard = false;
		paused = false;
		PCmo_MinerControlHandler.disconnectMinerFromKeyboardControl(this, true);

		alignToBlocks();
		resetStatus();

		commandList = parsed;
		commandListSaved = "";
	}

	// preserve fuel.
	private void resetStatus() {
		currentCommand = -1;
		roundYaw();
		targetX = (int) posX;
		targetZ = (int) posZ;
		resetMineCounter();
		stepCounter = 0;
		waitingForFuel = 0;
		fuelAllocated = 0;
		bridgeDone = false;
		upStepLaid = false;
	}

	public void setKeyboardControl(boolean yes) {
		keyboard = yes;
		if (yes) {
			pauseProgram();
			PCmo_MinerControlHandler.setMinerForKeyboardControl(this, false); // not silent
		} else {
			PCmo_MinerControlHandler.disconnectMinerFromKeyboardControl(this, false); // not
			// silent
			resumeProgram();
		}
	}

	public boolean readyForKeyboardCommand() {
		if (opennedGui != null) { return false; }
		commandList = commandList.trim();
		return true;
	}

	public boolean readyForUrgentKeyboardCommand() {
		return opennedGui == null;
	}

	public void sendKeyboardCommand(int i) {
		if (i == PCmo_Command.RUN_PROGRAM) {
			resetEverything();
			setKeyboardControl(false);
			try {
				runNewProgram();
			} catch (PCmo_CommandException e) {}
		}
		if (i == PCmo_Command.RESET) {
			resetEverything();
		} else {
			Character chr = PCmo_Command.getCharFromInt(i);
			if (chr.equals('?')) { return; }
			commandList += chr.toString();
		}
	}

	public void appendCode(String code) throws PCmo_CommandException {
		commandList = commandList + " " + PCmo_Command.parseCode(code);
	}

	public void setCode(String code) throws PCmo_CommandException {
		commandList = PCmo_Command.parseCode(code);
	}

	private int getNextCommand() {
		if (commandList.length() > 0) {
			Character first = commandList.charAt(0);

			int cmd = PCmo_Command.getIntFromChar(first);
			if (cmd != -1) {
				commandList = commandList.substring(1);
				if (cmd == PCmo_Command.FORWARD || cmd == PCmo_Command.BACKWARD || cmd == PCmo_Command.UP) {
					stepCounter = 1;
				}
				return cmd;
			} else if (Character.isDigit(first) || first.equals('-')) {
				String numbuff = Character.toString(first);
				commandList = commandList.substring(1);

				while (commandList.length() > 0) {
					first = Character.valueOf(commandList.charAt(0));

					if (Character.isDigit(first)) {
						numbuff += first.toString();
					} else {
						break;
					}
					commandList = commandList.substring(1);
				}

				try {
					stepCounter = Integer.valueOf(numbuff);
					cmd = stepCounter > 0 ? PCmo_Command.FORWARD : PCmo_Command.BACKWARD;

					stepCounter = Math.abs(stepCounter);
					if (stepCounter == 0) { return -1; }

					return cmd;

				} catch (NumberFormatException nfe) {
					return -1;
				}
			} else {
				commandList = commandList.substring(1);
				return getNextCommand();
			}
		}
		return -1;
	}

	// === EXECUTION AND STATUS UTILS ===

	private boolean targetTaken() {
		if (currentCommand == PCmo_Command.FORWARD || currentCommand == PCmo_Command.UP) {
			if (rotationYaw == 0) { return posX <= targetX; }
			if (rotationYaw == 90) { return posZ <= targetZ; }
			if (rotationYaw == 180) { return posX >= targetX; }
			if (rotationYaw == 270) { return posZ >= targetZ; }
		} else if (currentCommand == PCmo_Command.BACKWARD) {
			if (rotationYaw == 0) { return posX >= targetX; }
			if (rotationYaw == 90) { return posZ >= targetZ; }
			if (rotationYaw == 180) { return posX <= targetX; }
			if (rotationYaw == 270) { return posZ <= targetZ; }
		}
		return true;
	}

	private double getTargetDistanceX() {
		return Math.abs(posX - Math.round(targetX));
	}

	private double getTargetDistanceZ() {
		return Math.abs(posZ - Math.round(targetZ));
	}

	private void roundYaw() {

		if (rotationYaw < 0) {
			rotationYaw = prevRotationYaw = 360F - rotationYaw;
		}
		if (rotationYaw > 360F) {
			rotationYaw = prevRotationYaw = rotationYaw - 360F;
		}

		if (rotationYaw >= 315 || rotationYaw < 45) {
			prevRotationYaw = rotationYaw = 0;
		}
		if (rotationYaw >= 45 && rotationYaw < 135) {
			prevRotationYaw = rotationYaw = 90;
		}
		if (rotationYaw >= 135 && rotationYaw < 215) {
			prevRotationYaw = rotationYaw = 180;
		}
		if (rotationYaw >= 215 && rotationYaw < 315) {
			prevRotationYaw = rotationYaw = 270;
		}
		rotationRemaining = 0;
	}

	private void alignToBlocks() {
		setPosition(Math.round(posX), posY, Math.round(posZ));
	}

	private void prepareForCommandExecution() {
		if (currentCommand > -1) {
			realCommand = currentCommand;
			prevPosX = posX = (int) Math.round(posX);
			prevPosX = posZ = (int) Math.round(posZ);
			int x = (int) Math.round(posX);
			int z = (int) Math.round(posZ);
			int y = (int) Math.floor(posY + 0.0001F);

			roundYaw();

			if (currentCommand == PCmo_Command.DEPOSIT) {
				depositToNearbyChest();
				currentCommand = -1;

			} else if (currentCommand == PCmo_Command.DISASSEMBLY) {
				turnIntoBlocks();
				return;
			} else if (currentCommand == PCmo_Command.BRIDGE_ENABLE) {

				bridgeEnabled = true;
				currentCommand = -1;
			} else if (currentCommand == PCmo_Command.BRIDGE_DISABLE) {
				bridgeEnabled = false;
				currentCommand = -1;

			} else if (currentCommand == PCmo_Command.MINING_ENABLE) {
				miningEnabled = true;
				currentCommand = -1;
			} else if (currentCommand == PCmo_Command.MINING_DISABLE) {
				miningEnabled = false;
				currentCommand = -1;

			} else if (currentCommand == PCmo_Command.LAVA_ENABLE) {
				lavaFillingEnabled = true;
				currentCommand = -1;
			} else if (currentCommand == PCmo_Command.LAVA_DISABLE) {
				lavaFillingEnabled = false;
				currentCommand = -1;

			} else if (currentCommand == PCmo_Command.WATER_ENABLE) {
				waterFillingEnabled = true;
				currentCommand = -1;
			} else if (currentCommand == PCmo_Command.WATER_DISABLE) {
				waterFillingEnabled = false;
				currentCommand = -1;

			} else if (currentCommand == PCmo_Command.DOWN) {
				if (!miningEnabled) {
					currentCommand = -1;
				} else {
					resetMineCounter();
					mineCounter[4] = -1;
					mineCounter[5] = -1;
				}

			} else if (currentCommand == PCmo_Command.UP) {
				if (!miningEnabled) {
					currentCommand = -1;
				} else {
					if (addFuelForCost(getStepCost())) {

						resetMineCounter();
						if (rotationYaw == 0) {
							targetX = x - 1;
							targetZ = z;
						}
						if (rotationYaw == 90) {
							targetZ = z - 1;
							targetX = x;
						}
						if (rotationYaw == 180) {
							targetX = x + 1;
							targetZ = z;
						}
						if (rotationYaw == 270) {
							targetZ = z + 1;
							targetX = x;
						}

						if (!isOnHalfStep()) {
							// System.out.println("up "+posY);
							mineCounter[6] = -1;
							mineCounter[7] = -1;
							mineCounter[8] = -1;
							mineCounter[9] = -1;
							mineCounter[10] = -1;
							mineCounter[11] = -1;

							upStepLaid = false;
						} else {
							// System.out.println("forward + "+posY);
							currentCommand = PCmo_Command.FORWARD;

							// lay stepblock.
							switch ((int) Math.floor(rotationYaw)) {
								case 0:
									layHalfStep(x - 2, y, z - 1, false);
									layHalfStep(x - 2, y, z, false);
									break;

								case 90:
									layHalfStep(x - 1, y, z - 2, false);
									layHalfStep(x, y, z - 2, false);
									break;

								case 180:
									layHalfStep(x + 1, y, z - 1, false);
									layHalfStep(x + 1, y, z, false);
									break;

								case 270:
									layHalfStep(x - 1, y, z + 1, false);
									layHalfStep(x, y, z + 1, false);
									break;
							}

						}

					}
				}

			} else if (currentCommand == PCmo_Command.FORWARD) {
				if (addFuelForCost(getStepCost())) {
					resetMineCounter();
					bridgeDone = false;
					if (rotationYaw == 0) {
						targetX = x - 1;
						targetZ = z;
					}
					if (rotationYaw == 90) {
						targetZ = z - 1;
						targetX = x;
					}
					if (rotationYaw == 180) {
						targetX = x + 1;
						targetZ = z;
					}
					if (rotationYaw == 270) {
						targetZ = z + 1;
						targetX = x;
					}
				}

			} else if (currentCommand == PCmo_Command.BACKWARD) {
				if (addFuelForCost(getStepCost())) {
					bridgeDone = false;
					if (rotationYaw == 0) {
						targetX = x + 1;
						targetZ = z;
					}
					if (rotationYaw == 90) {
						targetZ = z + 1;
						targetX = x;
					}
					if (rotationYaw == 180) {
						targetX = x - 1;
						targetZ = z;
					}
					if (rotationYaw == 270) {
						targetZ = z - 1;
						targetX = x;
					}
				}

			} else if (currentCommand == PCmo_Command.LEFT) {

				rotationRemaining = -90;

			} else if (currentCommand == PCmo_Command.RIGHT) {

				rotationRemaining = 90;

			} else if (currentCommand == PCmo_Command.NORTH) {

				if (rotationYaw == 0) {
					currentCommand = PCmo_Command.RIGHT;
					rotationRemaining = 90;
				}
				if (rotationYaw == 180) {
					currentCommand = PCmo_Command.LEFT;
					rotationRemaining = -90;
				}
				if (rotationYaw == 90) {
					currentCommand = -1;
				}
				if (rotationYaw == 270) {
					currentCommand = PCmo_Command.LEFT;
					rotationRemaining = rand.nextBoolean() ? 180 : -180;
				}

			} else if (currentCommand == PCmo_Command.SOUTH) {

				if (rotationYaw == 0) {
					currentCommand = PCmo_Command.LEFT;
					rotationRemaining = -90;
				}
				if (rotationYaw == 180) {
					currentCommand = PCmo_Command.RIGHT;
					rotationRemaining = 90;
				}
				if (rotationYaw == 90) {
					currentCommand = PCmo_Command.LEFT;
					rotationRemaining = rand.nextBoolean() ? 180 : -180;
				}
				if (rotationYaw == 270) {
					currentCommand = -1;
				}

			} else if (currentCommand == PCmo_Command.EAST) {

				if (rotationYaw == 0) {
					currentCommand = PCmo_Command.LEFT;
					rotationRemaining = rand.nextBoolean() ? 180 : -180;
				}
				if (rotationYaw == 180) {
					currentCommand = -1;
				}
				if (rotationYaw == 90) {
					currentCommand = PCmo_Command.RIGHT;
					rotationRemaining = 90;
				}
				if (rotationYaw == 270) {
					currentCommand = PCmo_Command.LEFT;
					rotationRemaining = -90;
				}

			} else if (currentCommand == PCmo_Command.WEST) {

				if (rotationYaw == 0) {
					currentCommand = -1;
				}
				if (rotationYaw == 180) {
					currentCommand = PCmo_Command.LEFT;
					rotationRemaining = rand.nextBoolean() ? 180 : -180;
				}
				if (rotationYaw == 90) {
					currentCommand = PCmo_Command.LEFT;
					rotationRemaining = -90;
				}
				if (rotationYaw == 270) {
					currentCommand = PCmo_Command.RIGHT;
					rotationRemaining = 90;
				}

			} else {
				currentCommand = -1;
			}
		}
	}

	private int getStepCost() {
		return MathHelper.clamp_int(level / 2, 1, 4);
	}

	private boolean enableEffects() {
		return worldObj.getClosestPlayerToEntity(this, 17D) != null;
	}

	private void motionEffect() {
		if (!enableEffects()) { return; }
		worldObj.playSoundAtEntity(this, "random.click", 0.02F, 0.8F);
	}

	// HARVEST and perform animations.

	private void miningProgressEffect(int xx, int yy, int zz, int loc) {
		miningTickCounter++;

		if (!enableEffects()) { return; }
		int id = worldObj.getBlockId(xx, yy, zz);
		worldObj.getBlockMetadata(xx, yy, zz);

		Block block = Block.blocksList[id];
		if (miningTickCounter % 8 == 0 && block != null) {
			ModLoader.getMinecraftInstance().sndManager.playSound(block.stepSound.getBreakSound(), xx + 0.5F, yy + 0.5F, zz + 0.5F,
					(block.stepSound.getVolume() + 1.0F) / 8F, block.stepSound.getPitch() * 0.5F);
		}

		if (block != null) {
			ModLoader.getMinecraftInstance().effectRenderer.addBlockHitEffects(xx, yy, zz, loc < 4 ? getSideFromYaw() : (loc < 6 ? 1 : 0));
		}
	}

	private int getSideFromYaw() {
		if (rotationYaw == 0) { return 5; }
		if (rotationYaw == 90) { return 3; }
		if (rotationYaw == 180) { return 4; }
		if (rotationYaw == 270) { return 2; }
		return 1;
	}

	private void harvestBlock_do(int xx, int yy, int zz) {
		int id = worldObj.getBlockId(xx, yy, zz);
		int meta = worldObj.getBlockMetadata(xx, yy, zz);

		if (!ignoreBlockForHarvesting(id)) {
			Block.blocksList[id].harvestBlock(worldObj, dummyPlayer, xx, yy, zz, meta);
			worldObj.setBlockWithNotify(xx, yy, zz, 0);
			worldObj.playAuxSFX(2001, xx, yy, zz, id + (meta << 12));
		}

	}

	private void performMiningUpdate(int xx, int yy, int zz, int loc) {
		int id = worldObj.getBlockId(xx, yy, zz);
		worldObj.getBlockMetadata(xx, yy, zz);

		if (loc == 4 || loc == 5) {
			bridgeBuilding_do(xx, yy - 1, zz);
		}

		if (mineCounter[loc] <= 0) {

			if (ignoreBlockForHarvesting(id)) {
				if (mineCounter[loc] < 0) {
					mineCounter[loc] = 0;
				}
				return;
			}

			if (Block.blocksList[id] != null) {
				int cost = getBlockMiningCost(id);
				if (id == 7 && level == 8 && yy == 0) {
					cost = -1;
				}

				if (cost > 0) {
					if (addFuelForCost(cost)) {
						mineCounter[loc] = cost;
					}
				}
			}

		}

		if (waitingForFuel == 0 && mineCounter[loc] > 0) {
			int step = level;
			if (mineCounter[loc] < step) {
				step = mineCounter[loc];
				mineCounter[loc] = 0;
			} else {
				mineCounter[loc] -= step;
			}

			consumeAllocatedFuel(step);

			if (mineCounter[loc] == 0) {
				harvestBlock_do(xx, yy, zz);
			}
		}

		if (mineCounter[loc] != 0 && Block.blocksList[id] != null) {
			miningProgressEffect(xx, yy, zz, loc);
		}

	}

	private boolean isMiningInProgress() {
		for (int element : mineCounter) {
			if (element != 0) { return true; }
		}
		return false;
	}

	private boolean isMiningDone() {
		return !isMiningInProgress();
	}

	private void resetMineCounter() {
		for (int element : mineCounter) {
			fuelAllocated -= element;
			if (fuelAllocated <= 0) {
				fuelAllocated = 0;
				break;
			}
		}

		for (int i = 0; i < 4; i++) {
			mineCounter[i] = -1;
		}
		for (int i = 4; i < mineCounter.length; i++) {
			mineCounter[i] = 0;
		}
	}

	private boolean ignoreBlockForHarvesting(int id) {
		return id == 0 || Block.blocksList[id] == null || Block.blocksList[id] instanceof BlockTorch || id == Block.fire.blockID
				|| id == Block.portal.blockID || id == Block.endPortal.blockID || Block.blocksList[id] instanceof BlockFluid || id == 55
				|| id == 70 || id == 72 || PC_Utils.isBlockElevator(id) || PC_Utils.isBlockConveyor(id);
	}

	private boolean isBlockUnbreakable(int id) {
		return id == 7 || PC_Utils.isBlockHarvesterDelimiter(id);
	}

	private boolean canHarvestBlockWithCurrentLevel(int id) {
		if (id == 7 && level == 8) { return true; }
		if (isBlockUnbreakable(id)) { return false; }
		switch (level) {
			case 1: // all but rocks and iron
				return Block.blocksList[id].blockMaterial != Material.rock && Block.blocksList[id].blockMaterial != Material.iron
						&& id != mod_PCmobile.powerCrystal.blockID;
			case 2: // everything but precious ores (cobble, coal, iron)
				return id != 49 && id != 14 && id != 21 && id != 22 && id != 41 && id != 56 && id != 57 && id != 73 && id != 74
						&& id != mod_PCmobile.powerCrystal.blockID;
			case 3: // all but diamonds + obsidian + power crystals
				return id != 49 && id != 56 && id != 57 && id != mod_PCmobile.powerCrystal.blockID;
			case 4: // all but obsidian
				return id != 49;
			case 5:
			case 6:
			case 7:
			case 8:
				return true;
		}
		return false;
	}

	private int getBlockMiningCost(int id) {
		if (!canHarvestBlockWithCurrentLevel(id)) { return -1; }
		if (ignoreBlockForHarvesting(id)) { return 0; }

		// dirt, gravel, sand, non-rocks.
		if (Block.blocksList[id].blockMaterial != Material.rock && Block.blocksList[id].blockMaterial != Material.iron) { return 10; }
		if (id == 73 || id == 74 || id == 21 || id == 14) { return 100;// redstone,lapis,gold
		}
		if (id == 16 || id == 15 || id == 42 || id == 98) { return 30;// coal,iron,stonebrick
		}
		if (id == 56 || id == 57 || id == 14) { return 150; // diamond
		}
		if (id == 49) { return 600; }
		if (id == 7) { return 2000; }
		if (id == mod_PCmobile.powerCrystal.blockID) { return 100; }

		return 20;
	}

	private boolean checkLocationEmpty(int x, int y1, int z) {
		int y = y1;
		isOnHalfStep();
		// if(onstep) y=y+1;
		return checkIfAir(x, y, z, true) && checkIfAir(x, y + 1, z, false) && checkIfAir(x - 1, y, z, true)
				&& checkIfAir(x - 1, y + 1, z, false) && checkIfAir(x, y, z - 1, true) && checkIfAir(x, y + 1, z - 1, false)
				&& checkIfAir(x - 1, y, z - 1, true) && checkIfAir(x - 1, y + 1, z - 1, false);
	}

	private boolean checkIfAir(int x, int y, int z, boolean lower) {
		int id = worldObj.getBlockId(x, y, z);

		if (lower && id == Block.stairSingle.blockID) { return true; }

		Block block = Block.blocksList[id];
		return block == null || block.getCollisionBoundingBoxFromPool(worldObj, x, y, z) == null;
	}

	private boolean isOnHalfStep() {
		return (posY - Math.floor(posY + 0.0001)) >= 0.4D;
	}

	private boolean performBridgeBuilding() {
		if (!bridgeEnabled) { return true; }

		int y = (int) Math.floor(posY - 0.9999F);
		if (isOnHalfStep()) { return true; }
		if (!bridgeBuilding_do(targetX, y, targetZ)) { return false; }
		if (!bridgeBuilding_do(targetX - 1, y, targetZ)) { return false; }
		if (!bridgeBuilding_do(targetX, y, targetZ - 1)) { return false; }
		if (!bridgeBuilding_do(targetX - 1, y, targetZ - 1)) { return false; }

		return true;
	}

	private boolean bridgeBuilding_do(int x, int y, int z) {
		if (checkIfAir(x, y, z, false)) {
			if (level < 3) {
				currentCommand = -1;
				return false;
			}
			ItemStack fill = getBlockForBuilding();
			if (fill == null) { return false; }

			int id = fill.itemID;
			int meta = fill.getItemDamage();
			worldObj.setBlockAndMetadataWithNotify(x, y, z, id, meta);
			worldObj.playSoundEffect(x + 0.5F, y + 0.5F, z + 0.5F, Block.blocksList[id].stepSound.getStepSound(),
					(Block.blocksList[id].stepSound.getVolume() + 1.0F) / 2.0F, Block.blocksList[id].stepSound.getPitch() * 0.8F);
		}
		return true;
	}

	private void layHalfStep(int x, int y, int z, boolean step) {

		if (step) {
			if (worldObj.getBlockId(x, y, z) == 0) {
				int dmg = getDamageForHalfStep();
				if (dmg != -1) {
					worldObj.setBlockAndMetadataWithNotify(x, y, z, Block.stairSingle.blockID, dmg);
				}
			}
		}

		int id = worldObj.getBlockId(x, y + (step ? -1 : 0), z);
		if (id == 0 || id == 8 || id == 9 || id == 10 || id == 11
				|| Block.blocksList[id].getCollisionBoundingBoxFromPool(worldObj, x, y, z) == null) {
			ItemStack fill = getBlockForBuilding();
			if (fill == null) { return; }

			id = fill.itemID;
			int meta = fill.getItemDamage();
			worldObj.setBlockAndMetadataWithNotify(x, y + (step ? -1 : 0), z, id, meta);
			worldObj.playSoundEffect(x + 0.5F, (float) y + (step ? -1 : 0) + 0.5F, z + 0.5F, Block.blocksList[id].stepSound.getStepSound(),
					(Block.blocksList[id].stepSound.getVolume() + 1.0F) / 2.0F, Block.blocksList[id].stepSound.getPitch() * 0.8F);
		}
	}

	private int getDamageForHalfStep() {
		for (int pass = 0; pass < 3; pass++) {
			for (int i = 0; i < getSizeInventory(); i++) {
				if (isItemGoodForHalfStep(getStackInSlot(i), pass)) {
					ItemStack returned = decrStackSize(i, 1);

					if (returned.itemID == Block.stairSingle.blockID) { return returned.getItemDamage(); }
					return getDamageFromMaterialForHalfStep(returned.itemID);
				}
			}
		}
		return -1;
	}

	private int getDamageFromMaterialForHalfStep(int id) {
		switch (id) {
			case 1:
				return 0;
			case 4:
				return 3;
			case 5:
				return 2;
			case 24:
				return 1;
			case 45:
				return 4;
			case 98:
				return 5;
		}
		return 3;
	}

	private boolean isItemGoodForHalfStep(ItemStack is, int pass) {
		if (is == null) { return false; }
		int id = is.itemID;

		if (pass == 0) { return id == Block.cobblestone.blockID || id == Block.stairSingle.blockID; }

		if (pass == 1) { return id == Block.planks.blockID || id == Block.stone.blockID; }

		if (pass == 2) { return id == Block.sandStone.blockID || id == Block.stoneBrick.blockID || id == Block.brick.blockID; }

		return false;
	}

	private ItemStack getBlockForBuilding() {
		for (int pass = 0; pass < 3; pass++) {
			for (int i = 0; i < getSizeInventory(); i++) {
				if (isBlockGoodForBuilding(getStackInSlot(i), pass)) { return decrStackSize(i, 1); }
			}
		}
		return null;
	}

	private boolean isBlockGoodForBuilding(ItemStack is, int pass) {
		if (is == null) { return false; }
		int id = is.itemID;

		if (id == Block.sand.blockID || id == Block.gravel.blockID) { return false; }

		if (pass == 0) { return id == 2 || id == 3 || id == 4; }

		if (pass == 1) { return id == 5 || id == 1 || id == 24 || id == 87; }

		if (id == 15 || id == 14 || id == 56) { return false; }

		return (is.getItem() instanceof ItemBlock) && id != mod_PCmobile.powerCrystal.blockID && Block.blocksList[is.itemID] != null
				&& Block.blocksList[is.itemID].blockMaterial.isSolid();
	}

	private void compressInv() {
		if (level < 5) { return; }
		if (!compressBlocks) { return; }

		int sand = 0;
		int diamond = 0;
		int lapis = 0;
		int glowstone = 0;
		int snowball = 0;

		for (int pass = 0; pass < 3; pass++) {
			for (int i = 0; i < getSizeInventory(); i++) {
				if (getStackInSlot(i) != null) {
					if (getStackInSlot(i).itemID == Block.sand.blockID) {
						sand += getStackInSlot(i).stackSize;
						setInventorySlotContents(i, null);
						continue;
					}

					if (getStackInSlot(i).itemID == Item.diamond.shiftedIndex) {
						diamond += getStackInSlot(i).stackSize;
						setInventorySlotContents(i, null);
						continue;
					}

					if (getStackInSlot(i).itemID == Item.snowball.shiftedIndex) {
						snowball += getStackInSlot(i).stackSize;
						setInventorySlotContents(i, null);
						continue;
					}

					if (getStackInSlot(i).itemID == Item.lightStoneDust.shiftedIndex) {
						glowstone += getStackInSlot(i).stackSize;
						setInventorySlotContents(i, null);
						continue;
					}

					if (getStackInSlot(i).itemID == Item.dyePowder.shiftedIndex && getStackInSlot(i).getItemDamage() == 4) {
						lapis += getStackInSlot(i).stackSize;
						setInventorySlotContents(i, null);
						continue;
					}
				}
			}
		}

		if (sand > 0) {
			while (sand >= 4) {
				if (PC_InvUtils.addItemStackToInventory(this, new ItemStack(Block.sandStone.blockID, 1, 0))) {
					sand -= 4;
				} else {
					break;
				}
			}

			if (sand > 0) {
				ItemStack remaining = new ItemStack(Block.sand.blockID, sand, 0);
				if (!PC_InvUtils.addItemStackToInventory(this, remaining)) {
					entityDropItem(remaining, 1);
				}
			}
		}

		if (snowball > 0) {
			while (snowball >= 4) {
				if (PC_InvUtils.addItemStackToInventory(this, (new ItemStack(Block.blockSnow.blockID, 1, 0)))) {
					snowball -= 4;
				} else {
					break;
				}
			}

			if (snowball > 0) {
				ItemStack remaining = new ItemStack(Item.snowball.shiftedIndex, snowball, 0);
				if (!PC_InvUtils.addItemStackToInventory(this, remaining)) {
					entityDropItem(remaining, 1);
				}
			}
		}

		if (glowstone > 0) {
			while (glowstone >= 4) {
				if (PC_InvUtils.addItemStackToInventory(this, new ItemStack(Block.glowStone.blockID, 1, 0))) {
					glowstone -= 4;
				} else {
					break;
				}
			}

			if (glowstone > 0) {
				ItemStack remaining = new ItemStack(Item.lightStoneDust.shiftedIndex, glowstone, 0);
				if (!PC_InvUtils.addItemStackToInventory(this, remaining)) {
					entityDropItem(remaining, 1);
				}
			}
		}

		if (diamond > 0) {
			while (diamond >= 9) {
				if (PC_InvUtils.addItemStackToInventory(this, new ItemStack(Block.blockDiamond.blockID, 1, 0))) {
					diamond -= 9;
				} else {
					break;
				}
			}

			if (diamond > 0) {
				ItemStack remaining = new ItemStack(Item.diamond.shiftedIndex, diamond, 0);
				if (!PC_InvUtils.addItemStackToInventory(this, remaining)) {
					entityDropItem(remaining, 1);
				}
			}
		}

		if (lapis > 0) {
			while (lapis >= 9) {
				if (PC_InvUtils.addItemStackToInventory(this, new ItemStack(Block.blockLapis.blockID, 1, 0))) {
					lapis -= 9;
				} else {
					break;
				}
			}

			if (lapis > 0) {
				ItemStack remaining = new ItemStack(Item.dyePowder.shiftedIndex, lapis, 4);
				if (!PC_InvUtils.addItemStackToInventory(this, remaining)) {
					entityDropItem(remaining, 1);
				}
			}
		}

		return;
	}

	private void lavaFix() {
		if (level < 4 || !lavaFillingEnabled) { return; }

		int y1 = (int) Math.floor(posY + 0.0001F);
		int x1 = (int) Math.round(posX);
		int z1 = (int) Math.round(posZ);

		boolean replace = true;
		for (int x = x1 - 2; x <= x1 + 1; x++) {
			for (int y = y1 - 1; y <= y1 + 2; y++) {
				for (int z = z1 - 2; z <= z1 + 1; z++) {
					replace = !((y == y1 || y == y1 + 1) && (x == x1 || x == x1 - 1) && (z == z1 || z == z1 - 1));

					if (x == x1 - 2 && y == y1 - 1) {
						continue;
					}
					if (x == x1 - 2 && y == y1 + 2) {
						continue;
					}
					if (x == x1 + 1 && y == y1 - 1) {
						continue;
					}
					if (x == x1 + 1 && y == y1 + 2) {
						continue;
					}

					if (z == z1 - 2 && y == y1 - 1) {
						continue;
					}
					if (z == z1 - 2 && y == y1 + 2) {
						continue;
					}
					if (z == z1 + 1 && y == y1 - 1) {
						continue;
					}
					if (z == z1 + 1 && y == y1 + 2) {
						continue;
					}

					if (x == x1 - 2 && z == z1 - 2) {
						continue;
					}
					if (x == x1 - 2 && z == z1 + 1) {
						continue;
					}
					if (x == x1 + 1 && z == z1 - 2) {
						continue;
					}
					if (x == x1 + 1 && z == z1 + 1) {
						continue;
					}

					switch ((int) Math.floor(rotationYaw)) {
						case 180:
							if (x == x1 - 2) {
								replace = false;
							}
							break;
						case 270:
							if (z == z1 - 2) {
								replace = false;
							}
							break;
						case 0:
							if (x == x1 + 1) {
								replace = false;
							}
							break;
						case 90:
							if (z == z1 + 1) {
								replace = false;
							}
							break;
					}

					int id = worldObj.getBlockId(x, y, z);
					if (id == 10 || id == 11) {
						lavaFillBucket();
						int fillId = 0;
						int fillMeta = 0;
						if (replace) {
							ItemStack fill = getBlockForBuilding();
							if (fill != null) {
								fillId = fill.itemID;
								fillMeta = fill.getItemDamage();
							}
						}
						worldObj.setBlockAndMetadataWithNotify(x, y, z, fillId, fillMeta);
						if (Block.blocksList[fillId] != null) {
							worldObj.playSoundEffect(x + 0.5F, y + 0.5F, z + 0.5F, Block.blocksList[fillId].stepSound.getStepSound(),
									(Block.blocksList[fillId].stepSound.getVolume() + 1.0F) / 2.0F,
									Block.blocksList[fillId].stepSound.getPitch() * 0.8F);
						}
					}
				}
			}
		}
	}

	private void waterFix() {
		if (level < 6 || !waterFillingEnabled) { return; }

		int y1 = (int) Math.floor(posY + 0.000F);
		int x1 = (int) Math.round(posX);
		int z1 = (int) Math.round(posZ);

		boolean replace = true;
		for (int x = x1 - 2; x <= x1 + 1; x++) {
			for (int y = y1 - 1; y <= y1 + 2; y++) {
				for (int z = z1 - 2; z <= z1 + 1; z++) {
					replace = !((y == y1 || y == y1 + 1) && (x == x1 || x == x1 - 1) && (z == z1 || z == z1 - 1));

					if (x == x1 - 2 && y == y1 - 1) {
						continue;
					}
					if (x == x1 - 2 && y == y1 + 2) {
						continue;
					}
					if (x == x1 + 1 && y == y1 - 1) {
						continue;
					}
					if (x == x1 + 1 && y == y1 + 2) {
						continue;
					}

					if (z == z1 - 2 && y == y1 - 1) {
						continue;
					}
					if (z == z1 - 2 && y == y1 + 2) {
						continue;
					}
					if (z == z1 + 1 && y == y1 - 1) {
						continue;
					}
					if (z == z1 + 1 && y == y1 + 2) {
						continue;
					}

					if (x == x1 - 2 && z == z1 - 2) {
						continue;
					}
					if (x == x1 - 2 && z == z1 + 1) {
						continue;
					}
					if (x == x1 + 1 && z == z1 - 2) {
						continue;
					}
					if (x == x1 + 1 && z == z1 + 1) {
						continue;
					}

					switch ((int) Math.floor(rotationYaw)) {
						case 180:
							if (x == x1 - 2) {
								replace = false;
							}
							break;
						case 270:
							if (z == z1 - 2) {
								replace = false;
							}
							break;
						case 0:
							if (x == x1 + 1) {
								replace = false;
							}
							break;
						case 90:
							if (z == z1 + 1) {
								replace = false;
							}
							break;
					}

					int id = worldObj.getBlockId(x, y, z);
					if (id == 8 || id == 9) {
						int fillId = 0;
						int fillMeta = 0;
						if (replace) {
							ItemStack fill = getBlockForBuilding();
							if (fill != null) {
								fillId = fill.itemID;
								fillMeta = fill.getItemDamage();
							}
						}
						worldObj.setBlockAndMetadataWithNotify(x, y, z, fillId, fillMeta);
						if (Block.blocksList[fillId] != null) {
							worldObj.playSoundEffect(x + 0.5F, y + 0.5F, z + 0.5F, Block.blocksList[fillId].stepSound.getStepSound(),
									(Block.blocksList[fillId].stepSound.getVolume() + 1.0F) / 2.0F,
									Block.blocksList[fillId].stepSound.getPitch() * 0.8F);
						}
					}
				}
			}
		}
	}

	private void burriedFix(boolean tar) {

		int y1 = (int) Math.floor(posY + 0.0001F);

		if (isOnHalfStep()) {
			y1++;
		}

		int x1 = tar ? targetX : (int) Math.round(posX);
		int z1 = tar ? targetZ : (int) Math.round(posZ);

		for (int x = x1 - 1; x <= x1; x++) {
			for (int y = y1; y <= y1 + 1; y++) {
				for (int z = z1 - 1; z <= z1; z++) {
					int id = worldObj.getBlockId(x, y, z);

					// get entry for new blocks.
					if (id != 0
							&& (Block.blocksList[id] instanceof BlockSand || id == Block.cobblestone.blockID || id == Block.dirt.blockID)) {
						harvestBlock_do(x, y, z);
					}
				}
			}
		}

	}

	private void depositToNearbyChest() {

		int y1 = (int) Math.floor(posY + 0.0001F);
		int x1 = (int) Math.round(posX);
		int z1 = (int) Math.round(posZ);

		for (int x = x1 - 2; x <= x1 + 1; x++) {
			for (int y = y1; y <= y1 + 1; y++) {
				for (int z = z1 - 2; z <= z1 + 1; z++) {
					IInventory chest = PC_InvUtils.getCompositeInventoryAt(worldObj, x, y, z);
					if (chest != null) {
						// cycle through and deposit.
						for (int i = 0; i < getSizeInventory(); i++) {
							boolean stored = false;
							boolean crystal = false;
							ItemStack stack = getStackInSlot(i);
							if (stack != null && stack.itemID != mod_PCmobile.powerDust.shiftedIndex
									&& stack.itemID != Block.torchWood.blockID && stack.itemID != Item.bucketEmpty.shiftedIndex
									&& stack.itemID != Item.bucketLava.shiftedIndex && (!keepAllFuel || getFuelValue(stack) == 0)) {

								if (stack.itemID == mod_PCmobile.powerCrystal.blockID) {
									if (stack.stackSize <= 1) {
										continue;
									}
									crystal = true;
									stack = getStackInSlot(i).copy();
									stack.stackSize--;
									decrStackSize(i, stack.stackSize);
								}

								stored = PC_InvUtils.addWholeItemStackToInventory(chest, stack);

							}

							if (stored && !crystal) {
								setInventorySlotContents(i, null);
							}
						}

						worldObj.playSoundAtEntity(this, "random.pop", 0.2F, 0.5F + rand.nextFloat() * 0.3F);

						return;
					}
				}
			}
		}
	}

	private void performTorchPlacing() {
		if (level < 3) { return; }

		int y = (int) Math.floor(posY + 0.0001F);
		int x = (int) Math.round(posX);
		int z = (int) Math.round(posZ);

		if (getBrightness(1.0F) > 0.2F) { return; }
		if (handleWaterMovement()) { return; }

		if (!hasTorch()) { return; }

		int leftX = x, leftZ = z, rightX = x, rightZ = z;

		if (rotationYaw == 0) {
			rightZ = z - 1;
			leftZ = z;
		}
		if (rotationYaw == 90) {
			rightX = x;
			leftX = x - 1; /* rightZ=leftZ=z-1; */
		}
		if (rotationYaw == 180) {
			leftZ = z - 1;
			rightZ = z;
			rightX = leftX = x - 1;
		}
		if (rotationYaw == 270) {
			rightX = x - 1;
			leftX = x;
			leftZ = rightZ = z - 1;
		}

		Block torch = Block.torchWood;

		if (!torchesOnlyOnFloor) {
			if (worldObj.getBlockId(rightX, y + 1, rightZ) == 0 && torch.canPlaceBlockAt(worldObj, rightX, y + 1, rightZ)) {
				worldObj.setBlockWithNotify(rightX, y + 1, rightZ, torch.blockID);
				getTorch();
				return;
			}
			if (worldObj.getBlockId(leftX, y + 1, leftZ) == 0 && torch.canPlaceBlockAt(worldObj, leftX, y + 1, leftZ)) {
				worldObj.setBlockWithNotify(leftX, y + 1, leftZ, torch.blockID);
				getTorch();
				return;
			}
		}

		if (worldObj.getBlockId(rightX, y, rightZ) == 0 && torch.canPlaceBlockAt(worldObj, rightX, y, rightZ)) {
			worldObj.setBlockWithNotify(rightX, y, rightZ, torch.blockID);

			// set on floor if not building stairs.
			if (realCommand != PCmo_Command.UP) {
				Block.torchWood.onBlockPlaced(worldObj, rightX, y, rightZ, 1);
			}
			getTorch();
			return;
		}

		if (worldObj.getBlockId(leftX, y, leftZ) == 0 && torch.canPlaceBlockAt(worldObj, leftX, y, leftZ)) {
			worldObj.setBlockWithNotify(leftX, y, leftZ, torch.blockID);

			// set on floor if not building stairs.
			if (realCommand != PCmo_Command.UP) {
				Block.torchWood.onBlockPlaced(worldObj, leftX, y, leftZ, 1);
			}
			getTorch();
			return;
		}

		return;
	}

	private boolean getTorch() {
		for (int i = 0; i < getSizeInventory(); i++) {
			if (getStackInSlot(i) != null && getStackInSlot(i).itemID == Block.torchWood.blockID) {
				decrStackSize(i, 1);
				return true;
			}
		}
		return false;
	}

	private boolean hasTorch() {
		for (int i = 0; i < getSizeInventory(); i++) {
			if (getStackInSlot(i) != null && getStackInSlot(i).itemID == Block.torchWood.blockID) { return true; }
		}
		return false;
	}

	private boolean lavaFillBucket() {
		for (int i = 0; i < getSizeInventory(); i++) {
			if (getStackInSlot(i) != null) {
				int id = getStackInSlot(i).itemID;
				if (id == Item.bucketEmpty.shiftedIndex) {
					setInventorySlotContents(i, new ItemStack(Item.bucketLava, 1, 0));
					return true;
				}
			}
		}
		return false;
	}

	// === UPDATE TICK ===

	@SuppressWarnings("unchecked")
	@Override
	public void onUpdate() {
		super.onUpdate();

		// breaking animations.
		if (getTimeSinceHit() > 0) {
			setTimeSinceHit(getTimeSinceHit() - 1);
		}
		if (getDamageTaken() > 0) {
			setDamageTaken(getDamageTaken() - 1);
		}

		prevPosX = posX;
		prevPosY = posY;
		prevPosZ = posZ;

		Math.sqrt(motionX * motionX + motionZ * motionZ);

		// EXECUTE CURRENT COMMAND

		boolean stop = programmingGuiOpen;

		if (!stop) {
			if (waitingForFuel > 0) {
				if (addFuelForCost(waitingForFuel)) {
					waitingForFuel = 0;
					prepareForCommandExecution();
				}
			}

			freeAllocatedFuelIfNoLongerNeeded();
			if (waitingForFuel < 0) {
				waitingForFuel = 0;
			}
			if (currentCommand == -1 && waitingForFuel != 0) {
				waitingForFuel = 0;
			}

			if (waitingForFuel == 0) {

				// execute rotation and check if target angle is reached.
				if (PCmo_Command.isCommandTurn(currentCommand)) {
					motionX = motionZ = 0;
					posX = targetX;
					posZ = targetZ;

					if (Math.abs(rotationRemaining) < 3) {
						currentCommand = -1;
						posX = targetX;
						posZ = targetZ;
						rotationRemaining = 0;
						roundYaw();
					} else {
						motionEffect();
						int step = MathHelper.clamp_int(level, 3, 7);
						step = MathHelper.clamp_int(step, 0, Math.abs(rotationRemaining));

						int incr = rotationRemaining > 0 ? step : -step;
						rotationYaw = rotationYaw + incr;
						if (rotationYaw < 0) {
							rotationYaw = prevRotationYaw = 360F + rotationYaw;
						}
						if (rotationYaw > 360F) {
							rotationYaw = prevRotationYaw = rotationYaw - 360F;
						}

						rotationRemaining -= incr;
					}
				}

				if (currentCommand != -1) {
					burriedFix(false);
				}

				// check if movement destination is reached
				if (PCmo_Command.isCommandMove(currentCommand) || (currentCommand == PCmo_Command.UP && isMiningDone())) {

					roundYaw();
					performTorchPlacing();

					if (targetTaken()) {

						consumeAllocatedFuel(getStepCost());
						lavaFix();
						waterFix();

						if (getTargetDistanceX() > 0.03125D) {
							posX = prevPosX = targetX;
						}

						if (getTargetDistanceZ() > 0.03125D) {
							posZ = prevPosZ = targetZ;
						}

						stepCounter--;
						if (stepCounter <= 0) {
							currentCommand = -1;
							if (commandList.length() == 0) {
								motionX = 0;
								motionZ = 0;
							}
							stepCounter = 0;
						} else {
							// prepare next target position.
							prepareForCommandExecution();
						}
					}
				}

				// perform movement and optional mining forwards!
				// previous command may have set waitingForFuel to step cost.
				if (PCmo_Command.isCommandMove(currentCommand) || currentCommand == PCmo_Command.DOWN || currentCommand == PCmo_Command.UP) {

					roundYaw();

					boolean fw = (currentCommand == PCmo_Command.FORWARD);
					boolean dwn = (currentCommand == PCmo_Command.DOWN);
					boolean up = (currentCommand == PCmo_Command.UP);
					boolean back = (currentCommand == PCmo_Command.BACKWARD);

					// for checks
					int x = (int) Math.round(posX);
					int y = (int) Math.floor(posY + 0.0001F);
					if (isOnHalfStep()) {
						y += 1;
					}
					int z = (int) Math.round(posZ);

					boolean bridgeOk = true;
					if (!bridgeDone) {
						bridgeOk = performBridgeBuilding();
						if (!bridgeOk) {

						} else {
							bridgeDone = true;
						}
					}

					if (isMiningInProgress() || !bridgeOk) {
						motionX = motionZ = 0;
					}

					boolean miningDone = isMiningDone();

					boolean canMove = bridgeOk && !dwn && (!up || miningDone);

					if (up && !miningDone) {
						performMiningUpdate(x, y + 2, z, 8);
						performMiningUpdate(x - 1, y + 2, z, 9);
						performMiningUpdate(x, y + 2, z - 1, 10);
						performMiningUpdate(x - 1, y + 2, z - 1, 11);
					}

					double motionAdd = (MOTION_SPEED[level - 1] * ((fw || up) ? 1 : -1)) * 0.5D;

					if (rotationYaw == 180) {
						if (!miningDone && (!back) && miningEnabled) {
							performMiningUpdate(x + 1, y, z - 1, 0);
							performMiningUpdate(x + 1, y, z, 1);
							performMiningUpdate(x + 1, y + 1, z, 2);
							performMiningUpdate(x + 1, y + 1, z - 1, 3);

							if (dwn) {
								performMiningUpdate(x + 1, y - 1, z - 1, 4);
								performMiningUpdate(x + 1, y - 1, z, 5);
							}

							if (up) {
								performMiningUpdate(x + 1, y + 2, z - 1, 6);
								performMiningUpdate(x + 1, y + 2, z, 7);
							}
						}
						if (checkLocationEmpty(targetX, y, targetZ) && canMove) {
							motionX += motionAdd;
						}
						motionZ = 0;
					}

					if (rotationYaw == 270) {
						if (!miningDone && (!back) && miningEnabled) {

							performMiningUpdate(x - 1, y, z + 1, 0);
							performMiningUpdate(x, y, z + 1, 1);
							performMiningUpdate(x - 1, y + 1, z + 1, 2);
							performMiningUpdate(x, y + 1, z + 1, 3);

							if (dwn) {
								performMiningUpdate(x - 1, y - 1, z + 1, 4);
								performMiningUpdate(x, y - 1, z + 1, 5);
							}

							if (up) {
								performMiningUpdate(x - 1, y + 2, z + 1, 6);
								performMiningUpdate(x, y + 2, z + 1, 7);
							}

						}
						if (checkLocationEmpty(targetX, y, targetZ) && canMove) {
							motionZ += motionAdd;
						}
						motionX = 0;
					}

					if (rotationYaw == 0) {
						if (!miningDone && (!back) && miningEnabled) {

							performMiningUpdate(x - 2, y, z - 1, 0);
							performMiningUpdate(x - 2, y, z, 1);
							performMiningUpdate(x - 2, y + 1, z, 2);
							performMiningUpdate(x - 2, y + 1, z - 1, 3);

							if (dwn) {
								performMiningUpdate(x - 2, y - 1, z - 1, 4);
								performMiningUpdate(x - 2, y - 1, z, 5);
							}

							if (up) {
								performMiningUpdate(x - 2, y + 2, z - 1, 6);
								performMiningUpdate(x - 2, y + 2, z, 7);
							}
						}
						if (checkLocationEmpty(targetX, y, targetZ) && canMove) {
							motionX -= motionAdd;
						}
						motionZ = 0;
					}

					if (rotationYaw == 90) {
						if (!miningDone && (!back) && miningEnabled) {

							performMiningUpdate(x - 1, y, z - 2, 0);
							performMiningUpdate(x, y, z - 2, 1);
							performMiningUpdate(x - 1, y + 1, z - 2, 2);
							performMiningUpdate(x, y + 1, z - 2, 3);
							if (dwn) {
								performMiningUpdate(x - 1, y - 1, z - 2, 4);
								performMiningUpdate(x, y - 1, z - 2, 5);
							}

							if (up) {
								performMiningUpdate(x - 1, y + 2, z - 2, 6);
								performMiningUpdate(x, y + 2, z - 2, 7);
							}
						}
						if (checkLocationEmpty(targetX, y, targetZ) && canMove) {
							motionZ -= motionAdd;
						}
						motionX = 0;
					}

					if (dwn && !isMiningInProgress()) {
						currentCommand = -1;
					}

					if (up && isMiningDone() && !upStepLaid) {
						switch ((int) Math.floor(rotationYaw)) {
							case 0:
								layHalfStep(x - 2, y, z - 1, true);
								layHalfStep(x - 2, y, z, true);
								break;

							case 90:
								layHalfStep(x - 1, y, z - 2, true);
								layHalfStep(x, y, z - 2, true);
								break;

							case 180:
								layHalfStep(x + 1, y, z - 1, true);
								layHalfStep(x + 1, y, z, true);
								break;

							case 270:
								layHalfStep(x - 1, y, z + 1, true);
								layHalfStep(x, y, z + 1, true);
								break;
						}
						upStepLaid = true;
					}

					// stop if bumped into wall
					if ((!miningEnabled || !isMiningInProgress() || currentCommand == PCmo_Command.BACKWARD)
							&& !checkLocationEmpty(targetX, y, targetZ)) {
						burriedFix(fw && miningEnabled);

						if (!checkLocationEmpty(targetX, y, targetZ)) {
							if (!miningEnabled || currentCommand == PCmo_Command.BACKWARD) {
								currentCommand = -1;
								resetMineCounter();
								consumeAllocatedFuel(getStepCost());
								targetX = (int) Math.round(posX);
								targetZ = (int) Math.round(posZ);

								stepCounter = 0;
							}
							motionX = motionZ = 0;
							/*
							 * lavaFix();
							 * waterFix();
							 */
						}
					}

				}

			}

		}

		// FALL
		if (!onGround) {
			motionY -= 0.04D;
		}

		// speed limit.
		double d7 = MOTION_SPEED[level - 1];
		if (motionX < -d7) {
			motionX = -d7;
		}
		if (motionX > d7) {
			motionX = d7;
		}
		if (motionZ < -d7) {
			motionZ = -d7;
		}
		if (motionZ > d7) {
			motionZ = d7;
		}

		// GET NEW COMMAND FROM QUEUE
		if (!stop && onGround && currentCommand == -1 && commandList.length() > 0) {
			int oldCmd = currentCommand;
			currentCommand = getNextCommand(); // gets command and removes it
												// from queue
			if (currentCommand != -1 && currentCommand != oldCmd) {
				alignToBlocks();
			}
			if (currentCommand == -1 && !keyboard) {
				alignToBlocks();
			}

			prepareForCommandExecution();

			if (currentCommand != -1) {
				setSprinting(true);
			}
		}

		// slow down if no more commands are available (halt)
		if (currentCommand == -1 && commandList.length() == 0) {
			motionX = 0D;
			motionZ = 0D;
			setSprinting(false);
		}

		if (Math.abs(motionX) > 0.0001D || Math.abs(motionZ) > 0.0001D) {
			motionEffect();
		}

		// pick up items.
		List<EntityItem> list;

		list = worldObj.getEntitiesWithinAABB(net.minecraft.src.EntityItem.class, boundingBox.expand(1.5D, 0.5D, 1.5D));
		if (list != null && list.size() > 0) {
			for (int j1 = 0; j1 < list.size(); j1++) {
				EntityItem entity = (EntityItem) list.get(j1);
				if (entity.delayBeforeCanPickup >= 7) {
					continue;
				}

				int id = entity.item.itemID;
				int dmg = entity.item.getItemDamage();

				boolean xtal = id == mod_PCmobile.powerCrystal.blockID;
				boolean compress = (id == Block.sand.blockID || id == Item.snowball.shiftedIndex || id == Item.diamond.shiftedIndex
						|| (id == Item.dyePowder.shiftedIndex && dmg == 4) || id == Item.lightStoneDust.shiftedIndex);

				if (destroyStack(entity.item)) {
					entity.setDead();
					continue;
				}

				if (PC_InvUtils.addItemStackToInventory(this, entity.item)) {
					entity.setDead();
				}
				if (xtal) {
					updateLevel();
				}
				if (compress && compressBlocks) {
					compressInv();
				}
			}
		}

		// push items
		list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.expand(0.2D, 0.01D, 0.2D));
		if (list != null && list.size() > 0) {
			for (int j1 = 0; j1 < list.size(); j1++) {
				Entity entity = (Entity) list.get(j1);
				if (entity instanceof EntityFX) {
					continue;
				}
				if (entity.isDead) {
					continue;
				}

				if (entity instanceof EntityArrow) {
					PC_InvUtils.addItemStackToInventory(this, new ItemStack(Item.arrow, 1, 0));
					entity.setDead();
					return;
				}

				// keep the same old velocity
				double motionX_prev = motionX;
				double motionY_prev = motionY;
				double motionZ_prev = motionZ;

				entity.applyEntityCollision(this);

				motionX = motionX_prev;
				motionY = motionY_prev;
				motionZ = motionZ_prev;
			}
		}

		moveEntity(Math.min(motionX, getTargetDistanceX()), motionY, Math.min(motionZ, getTargetDistanceZ()));
		motionX *= 0.7D;
		motionZ *= 0.7D;

	}

	// obsolete riding fuction.
	// @Override
	// public void updateRiderPosition() {
	// if (riddenByEntity == null) {
	// return;
	// } else {
	// double d = Math.cos((rotationYaw * 3.1415926535897931D) / 180D) *
	// 0.40000000000000002D;
	// double d1 = Math.sin((rotationYaw * 3.1415926535897931D) / 180D) *
	// 0.40000000000000002D;
	// riddenByEntity.setPosition(posX + d, posY + getMountedYOffset() +
	// riddenByEntity.getYOffset(), posZ + d1);
	// return;
	// }
	// }

	@Override
	public void applyEntityCollision(Entity entity) {
		if (entity.riddenByEntity == this || entity.ridingEntity == this) { return; }

		double d = entity.posX - posX;
		double d1 = entity.posZ - posZ;
		double d2 = MathHelper.abs_max(d, d1);
		if (d2 >= 0.0099999997764825821D) {
			d2 = MathHelper.sqrt_double(d2);
			d /= d2;
			d1 /= d2;
			double d3 = 1.0D / d2;
			if (d3 > 1.0D) {
				d3 = 1.0D;
			}
			d *= d3;
			d1 *= d3;
			d *= 0.05000000074505806D;
			d1 *= 0.05000000074505806D;
			d *= 1.0F - entityCollisionReduction;
			d1 *= 1.0F - entityCollisionReduction;
			isAirBorne = true;

			// this entity won't be moved!

			entity.addVelocity(d, 0.0D, d1);
		}
	}

	// NBT TAGs

	@Override
	protected void writeEntityToNBT(NBTTagCompound tag) {
		NBTTagCompound code = new NBTTagCompound();

		code.setString("CommandList", commandList);
		code.setShort("CurrentCommand", (short) currentCommand);
		code.setShort("RealCommand", (short) realCommand);
		code.setShort("StepCounter", (short) stepCounter);

		code.setString("CommandListSaved", commandListSaved);
		code.setString("Program", program);
		code.setBoolean("Paused", paused);
		code.setBoolean("Keyboard", keyboard);

		tag.setTag("MinerCode", code);

		NBTTagCompound status = new NBTTagCompound();

		status.setByte("Level", (byte) level);
		status.setShort("RotationRemaining", (short) rotationRemaining);
		status.setInteger("targetX", targetX);
		status.setInteger("targetZ", targetZ);
		status.setInteger("fuelBuffer", fuelBuffer);
		status.setInteger("fuelAllocated", fuelAllocated);
		status.setInteger("waitingForFuel", waitingForFuel);
		status.setBoolean("miningEnabled", miningEnabled);
		status.setBoolean("bridgeEnabled", bridgeEnabled);
		status.setBoolean("lavaFillingEnabled", lavaFillingEnabled);
		status.setBoolean("waterEnabled", waterFillingEnabled);
		status.setBoolean("keepAllFuel", keepAllFuel);
		status.setBoolean("torchesOnlyOnFloor", torchesOnlyOnFloor);
		status.setBoolean("craftCompress", compressBlocks);
		status.setByte("Destroy", DESTROY);

		status.setInteger("waitingForFuel", waitingForFuel);

		status.setInteger("mineTime0", mineCounter[0]);
		status.setInteger("mineTime1", mineCounter[1]);
		status.setInteger("mineTime2", mineCounter[2]);
		status.setInteger("mineTime3", mineCounter[3]);
		status.setInteger("mineTime4", mineCounter[4]);
		status.setInteger("mineTime5", mineCounter[5]);

		tag.setTag("MinerStatus", status);

		NBTTagList nbttaglist = new NBTTagList();

		for (int i = 0; i < cargoStacks.length; i++) {
			if (cargoStacks[i] != null) {
				NBTTagCompound nbttagcompound1 = new NBTTagCompound();
				nbttagcompound1.setByte("Slot", (byte) i);
				cargoStacks[i].writeToNBT(nbttagcompound1);
				nbttaglist.appendTag(nbttagcompound1);
			}
		}

		tag.setTag("Items", nbttaglist);
	}

	@Override
	protected void readEntityFromNBT(NBTTagCompound tag) {
		NBTTagCompound code = tag.getCompoundTag("MinerCode");

		commandList = code.getString("CommandList");
		currentCommand = code.getShort("CurrentCommand");
		realCommand = code.getShort("RealCommand");
		stepCounter = code.getShort("StepCounter");

		commandListSaved = code.getString("CommandListSaved");
		program = code.getString("Program");
		paused = code.getBoolean("Paused");
		keyboard = code.getBoolean("Keyboard");

		NBTTagCompound status = tag.getCompoundTag("MinerStatus");

		level = MathHelper.clamp_int(status.getByte("Level"), 1, 8);
		rotationRemaining = status.getShort("RotationRemaining");
		targetX = status.getInteger("targetX");
		targetZ = status.getInteger("targetZ");
		fuelBuffer = status.getInteger("fuelBuffer");
		fuelAllocated = status.getInteger("fuelAllocated");
		waitingForFuel = status.getInteger("waitingForFuel");
		miningEnabled = status.getBoolean("miningEnabled");
		bridgeEnabled = status.getBoolean("bridgeEnabled");
		lavaFillingEnabled = status.getBoolean("lavaFillingEnabled");
		waterFillingEnabled = status.getBoolean("waterEnabled");
		keepAllFuel = status.getBoolean("keepAllFuel");
		torchesOnlyOnFloor = status.getBoolean("torchesOnlyOnFloor");
		compressBlocks = status.getBoolean("craftCompress");

		DESTROY = status.getByte("Destroy");

		waitingForFuel = status.getInteger("waitingForFuel");

		mineCounter[0] = status.getInteger("mineTime0");
		mineCounter[1] = status.getInteger("mineTime1");
		mineCounter[2] = status.getInteger("mineTime2");
		mineCounter[3] = status.getInteger("mineTime3");
		mineCounter[4] = status.getInteger("mineTime4");
		mineCounter[5] = status.getInteger("mineTime5");

		NBTTagList nbttaglist = tag.getTagList("Items");

		cargoStacks = new ItemStack[getSizeInventory()];
		for (int i = 0; i < nbttaglist.tagCount(); i++) {
			NBTTagCompound nbttagcompound1 = (NBTTagCompound) nbttaglist.tagAt(i);
			int j = nbttagcompound1.getByte("Slot") & 0xff;
			if (j >= 0 && j < cargoStacks.length) {
				cargoStacks[j] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
			}
		}

		if (keyboard) {
			PCmo_MinerControlHandler.setMinerForKeyboardControl(this, true);
		}
	}

	// === PLAYER INTERACTION ===

	GuiScreen opennedGui = null;

	@Override
	public boolean interact(EntityPlayer entityplayer) {
		if (riddenByEntity != null && (riddenByEntity instanceof EntityPlayer) && riddenByEntity != entityplayer) { return true; }

		if (!worldObj.isRemote) {
			if (entityplayer.isSneaking()) {
				programmingGuiOpen = true;
				opennedGui = new PCmo_GuiMinerConsole(this);
				ModLoader.openGUI(entityplayer, opennedGui);
				return true;
			}

			// set for keyboard control or open gui.
			if (entityplayer.getCurrentEquippedItem() != null
					&& entityplayer.getCurrentEquippedItem().itemID == mod_PCmobile.activator.shiftedIndex) {
				setKeyboardControl(!keyboard);

			} else if (entityplayer.getCurrentEquippedItem() != null
					&& entityplayer.getCurrentEquippedItem().itemID == Item.stick.shiftedIndex) {
				PC_Utils.chatMsg(rotationYaw + "°", true);
				PC_Utils.chatMsg("PROGRAM: " + program, false);
				PC_Utils.chatMsg("Buffer: " + commandList.length() + " commands.", false);
				PC_Utils.chatMsg("Inctruction = " + Character.toString(PCmo_Command.getCharFromInt(currentCommand)) + ", Step counter = "
						+ stepCounter, false);
				PC_Utils.chatMsg("FUEL: burning = " + fuelBuffer + ", allocated = " + fuelAllocated + ", deficit = " + waitingForFuel,
						false);
				PC_Utils.chatMsg("bridge = " + bridgeEnabled + ", mining = " + miningEnabled + ", destroy_flags = " + DESTROY, false);

			} else {
				opennedGui = new GuiChest(entityplayer.inventory, this);
				ModLoader.openGUI(entityplayer, opennedGui);
			}
		}
		return true;
	}

	// === WATCHER ===

	public void setDamageTaken(int i) {
		dataWatcher.updateObject(19, Integer.valueOf(i));
	}

	public int getDamageTaken() {
		return dataWatcher.getWatchableObjectInt(19);
	}

	public void setTimeSinceHit(int i) {
		dataWatcher.updateObject(17, Integer.valueOf(i));
	}

	public int getTimeSinceHit() {
		return dataWatcher.getWatchableObjectInt(17);
	}

	public void setForwardDirection(int i) {
		dataWatcher.updateObject(18, Integer.valueOf(i));
	}

	public int getForwardDirection() {
		return dataWatcher.getWatchableObjectInt(18);
	}

	// === INVENTORY ===

	private ItemStack[] cargoStacks = new ItemStack[54];

	@Override
	public int getSizeInventory() {
		return 54;
	}

	@Override
	public ItemStack getStackInSlot(int i) {
		return cargoStacks[i];
	}

	@Override
	public int getInventoryStackLimit() {
		return 64;
	}

	@Override
	public ItemStack decrStackSize(int i, int j) {
		if (cargoStacks[i] != null) {
			if (cargoStacks[i].stackSize <= j) {
				ItemStack itemstack = cargoStacks[i];
				cargoStacks[i] = null;
				onInventoryChanged();
				return itemstack;
			}
			ItemStack itemstack1 = cargoStacks[i].splitStack(j);
			if (cargoStacks[i].stackSize == 0) {
				cargoStacks[i] = null;
			}
			onInventoryChanged();
			return itemstack1;
		} else {
			return null;
		}
	}

	@Override
	public void setInventorySlotContents(int i, ItemStack itemstack) {
		cargoStacks[i] = itemstack;
		if (itemstack != null && itemstack.stackSize > getInventoryStackLimit()) {
			itemstack.stackSize = getInventoryStackLimit();
		}
		onInventoryChanged();
	}

	@Override
	public String getInvName() {
		return "Miner Cargo Storage";
	}

	@Override
	public boolean isUseableByPlayer(EntityPlayer entityplayer) {
		return entityplayer.getDistanceSq(posX, posY, posZ) <= 64D;
	}

	@Override
	public void openChest() {};

	@Override
	public void closeChest() {
		opennedGui = null;

		updateLevel();
	}

	private void updateLevel() {
		if (!building) {
			int cnt = countPowerCrystals();
			if (cnt == 0) {
				turnIntoBlocks();
				return;
			}

			level = Math.min(cnt, 8);

			bridgeEnabled &= (level >= 3);
			waterFillingEnabled &= (level >= 6);
			lavaFillingEnabled &= (level >= 4);
		}
	}

	@Override
	public void onInventoryChanged() {}

	// === CRYSTAL COUNTING AND TURNING INTO BLOCKS ===

	private void turnIntoBlocks() {
		building = true;
		int x = (int) Math.round(posX);
		int y = (int) Math.floor(posY + 0.0001F);
		int z = (int) Math.round(posZ);
		int yaw = (rotationYaw < 45 || rotationYaw > 315) ? 0 : (rotationYaw < 135 ? 1 : (rotationYaw < 215 ? 2 : (rotationYaw < 315 ? 3
				: 0)));

		int i1 = x - 1, k1 = z - 1;
		int i2 = x, k2 = z;

		// building chests
		for (int i = i1; i <= i2; i++) {
			for (int k = k1; k <= k2; k++) {
				worldObj.setBlockWithNotify(i, y, k, Block.blockSteel.blockID);
				if ((yaw == 0 && i == i2) || (yaw == 1 && k == k2) || (yaw == 2 && i == i1) || (yaw == 3 && k == k1)) {
					worldObj.setBlockWithNotify(i, y + 1, k, Block.chest.blockID);
				} else {
					worldObj.setBlockWithNotify(i, y + 1, k, Block.blockSteel.blockID);
				}
			}
		}

		IInventory inv = null;

		test:
		for (int i = i1; i <= i2; i++) {
			for (int k = k1; k <= k2; k++) {
				inv = PC_InvUtils.getCompositeInventoryAt(worldObj, i, y + 1, k);
				if (inv != null) {
					break test;
				}
			}
		}

		if (inv != null) {
			for (int i = 0; i < Math.min(inv.getSizeInventory(), getSizeInventory()); i++) {
				inv.setInventorySlotContents(i, getStackInSlot(i));
				setInventorySlotContents(i, null);
			}
		} else {
			System.out.println("Chest not found!");
		}

		setDead();

		// replace opened gui with chest.
		if (opennedGui != null) {
			ModLoader.getMinecraftInstance().thePlayer.closeScreen();
			ModLoader.openGUI(ModLoader.getMinecraftInstance().thePlayer, new GuiChest(
					ModLoader.getMinecraftInstance().thePlayer.inventory, inv));
		}

	}

	// counting power crystals inside chest
	private int countPowerCrystals() {
		boolean[] foundTable = { false, false, false, false, false, false, false, false };

		for (int i = 0; i < getSizeInventory(); i++) {
			if (cargoStacks[i] != null && cargoStacks[i].itemID == mod_PCmobile.powerCrystal.blockID) {
				foundTable[MathHelper.clamp_int(cargoStacks[i].getItemDamage(), 0, 7)] = true;
			}
		}

		int cnt = 0;
		for (int i = 0; i < 8; i++) {
			if (foundTable[i]) {
				cnt++;
			}
		}

		return cnt;
	}

	// === FUEL STUFF ===
	private void consumeAllocatedFuel(int count) {
		fuelAllocated -= count;
		fuelBuffer -= count;
		if (fuelBuffer < 0) {
			fuelBuffer = 0;
		}
		if (fuelAllocated < 0) {
			fuelAllocated = 0;
		}
	}

	private void freeAllocatedFuelIfNoLongerNeeded() {
		if (!isMiningInProgress() && currentCommand == -1) {
			fuelAllocated = 0;
		}
	}

	private boolean addFuelForCost(int cost) {

		if (fuelBuffer - fuelAllocated >= cost) {
			fuelAllocated += cost;
			return true;
		} else {
			for (int s = 0; s < getSizeInventory(); s++) {
				ItemStack stack = getStackInSlot(s);
				int bt = getFuelValue(stack);
				if (bt > 0) {
					fuelBuffer += bt;
					if (stack.getItem().hasContainerItem()) {
						setInventorySlotContents(s, new ItemStack(stack.getItem().getContainerItem(), 1, 0));
					} else {
						decrStackSize(s, 1);
					}

					if ((fuelBuffer - fuelAllocated) >= cost) {
						fuelAllocated += cost;
						return true;
					}
				}
			}

			if ((fuelBuffer - fuelAllocated) >= cost) {
				fuelAllocated += cost;
				return true;
			}
		}

		waitingForFuel += cost - (fuelBuffer + fuelAllocated);
		return false;
	}

	private static final double FUEL_STRENGTH = 0.9D;

	private int getFuelValue(ItemStack itemstack) {
		if (itemstack == null) { return 0; }
		int i = itemstack.getItem().shiftedIndex;
		if (i < 256 && Block.blocksList[i].blockMaterial == Material.wood) { return (int) (300 * FUEL_STRENGTH); }
		if (i == Item.stick.shiftedIndex) { return (int) (100 * FUEL_STRENGTH); }
		if (i == Item.coal.shiftedIndex) { return (int) (1600 * FUEL_STRENGTH); }
		if (i == Item.bucketLava.shiftedIndex) { return (int) (20000 * FUEL_STRENGTH); }
		if (i == Block.sapling.blockID) { return (int) (100 * FUEL_STRENGTH); }
		if (i == Item.gunpowder.shiftedIndex) { return (int) (500 * FUEL_STRENGTH); }
		if (i == Item.blazeRod.shiftedIndex) {
			return (int) (2400 * FUEL_STRENGTH);
		} else {
			return (int) (ModLoader.addAllFuel(i, itemstack.getItemDamage()) * FUEL_STRENGTH);
		}
	}

	@Override
	public ItemStack getStackInSlotOnClosing(int par1) {
		if (cargoStacks[par1] != null) {
			ItemStack itemstack = cargoStacks[par1];
			cargoStacks[par1] = null;
			return itemstack;
		} else {
			return null;
		}
	}

}
