diff options
3 files changed, 476 insertions, 264 deletions
diff --git a/src/main/java/gregtech/common/misc/GT_DrillingLogicDelegate.java b/src/main/java/gregtech/common/misc/GT_DrillingLogicDelegate.java new file mode 100644 index 0000000000..8f06f70140 --- /dev/null +++ b/src/main/java/gregtech/common/misc/GT_DrillingLogicDelegate.java @@ -0,0 +1,234 @@ +package gregtech.common.misc; + +import java.util.List; + +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.util.GT_Log; +import gregtech.api.util.GT_ModHandler; +import gregtech.api.util.GT_Utility; +import gregtech.common.blocks.GT_TileEntity_Ores; +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.util.FakePlayer; +import static gregtech.api.enums.GT_Values.debugBlockMiner; + +/** @author Relvl on 27.01.2022 */ +@SuppressWarnings("ObjectEquality") +public class GT_DrillingLogicDelegate { + public static final ItemStack MINING_PIPE_STACK = GT_ModHandler.getIC2Item("miningPipe", 0); + public static final Block MINING_PIPE_BLOCK = GT_Utility.getBlockFromStack(MINING_PIPE_STACK); + public static final Block MINING_PIPE_TIP_BLOCK = GT_Utility.getBlockFromStack(GT_ModHandler.getIC2Item("miningPipeTip", 0)); + + /** The owner machine pointer */ + private final GT_IDrillingLogicDelegateOwner owner; + + /** Is pipe retracting process done and halts? */ + private boolean isRetractDone; + /** Is machine ran out of mining pipes in its inventory and halts? */ + private boolean isWaitingForPipeItem; + /** Pipe tip depth (relative to machine Y position, NEGATIVE). */ + private int tipDepth; + /** Cached fake player */ + private FakePlayer mFakePlayer; + + public GT_DrillingLogicDelegate(GT_IDrillingLogicDelegateOwner owner) { + this.owner = owner; + } + + /** Descents a pipe tip one plock deeper. */ + public boolean descent(IGregTechTileEntity te) { + if (!te.isAllowedToWork()) { + return false; + } + + int xCoord = te.getXCoord(); + int zCoord = te.getZCoord(); + int yCoord = te.getYCoord(); + int checkY = yCoord + tipDepth - 1; + boolean isHitsTheVoid = checkY < 0; + boolean isHitsBedrock = GT_Utility.getBlockHardnessAt(te.getWorld(), xCoord, checkY, zCoord) < 0; + boolean isFakePlayerAllowed = canFakePlayerInteract(te, xCoord, checkY, zCoord); + + if (isHitsTheVoid || isHitsBedrock || !isFakePlayerAllowed) { + // Disable and start retracting process. + te.disableWorking(); + if (debugBlockMiner) { + if (isHitsTheVoid) { + GT_Log.out.println("MINER: Hit bottom"); + } + if (isHitsBedrock) { + GT_Log.out.println("MINER: Hit block with -1 hardness"); + } + if (!isFakePlayerAllowed) { + GT_Log.out.println("MINER: Unable to set mining pipe tip"); + } + } + return false; + } + + // Replace the tip onto pipe + if (te.getBlockOffset(0, tipDepth, 0) == MINING_PIPE_TIP_BLOCK) { + te.getWorld().setBlock(xCoord, yCoord + tipDepth, zCoord, MINING_PIPE_BLOCK); + } + // Get and decrease pipe from the machine + boolean pipeTaken = owner.pullInputs(MINING_PIPE_STACK.getItem(), 1, false); + if (!pipeTaken) { + // If there was nothing - waiting for the pipes (just for prevent unnecessary checks) + isWaitingForPipeItem = true; + return false; + } + + // If there is something - mine it + Block block = te.getBlockOffset(0, tipDepth - 1, 0); + if (!block.isAir(te.getWorld(), xCoord, yCoord, zCoord)) { + mineBlock(te, block, xCoord, yCoord + tipDepth - 1, zCoord); + } + + // Descent the pipe tip + te.getWorld().setBlock(xCoord, yCoord + tipDepth - 1, zCoord, MINING_PIPE_TIP_BLOCK); + tipDepth--; + return true; + } + + public void onOwnerPostTick(IGregTechTileEntity te, long tick) { + // If the machine was disabled - try to retract pipe + if (!te.isAllowedToWork()) { + onPostTickRetract(te, tick); + return; + } + // If the machine was re-enabled - we should reset the retracting process + isRetractDone = false; + } + + /** If the machine are disabled - tried to retract pipe. */ + private void onPostTickRetract(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { + if (isRetractDone) { + return; + } + // If retracting process just touch the miner + if (tipDepth == 0) { + isRetractDone = true; + return; + } + // Once per N ticks (depends on tier) + if ((aTick % (owner.getMachineSpeed() / 5)) != 0) { + return; + } + + // Check we can push pipe back to machine (inputs allowed for this case!) + boolean canPush = owner.pushOutputs(MINING_PIPE_STACK, 1, true, true); + if (!canPush) { + return; + } + + // Inspect target block - it should be a pipe tip, else something went wrong. + Block targetBlock = aBaseMetaTileEntity.getBlockOffset(0, tipDepth, 0); + if (targetBlock != MINING_PIPE_TIP_BLOCK && targetBlock != MINING_PIPE_BLOCK) { + return; + } + + // Retract the pipe/tip + int xCoord = aBaseMetaTileEntity.getXCoord(); + int yCoord = aBaseMetaTileEntity.getYCoord(); + int zCoord = aBaseMetaTileEntity.getZCoord(); + int actualDrillY = yCoord + tipDepth; + // Move the pipe tip position + if (actualDrillY < yCoord - 1) { + owner.getBaseMetaTileEntity().getWorld().setBlock(xCoord, actualDrillY + 1, zCoord, MINING_PIPE_TIP_BLOCK); + } + // Remove the old pipe tip + aBaseMetaTileEntity.getWorld().setBlock(xCoord, actualDrillY, zCoord, Blocks.air, 0, /*send to client without neighbour updates*/2); + + // Return the pipe back to the machine (inputs allowed for this case!) + owner.pushOutputs(MINING_PIPE_STACK, 1, false, true); + + tipDepth++; + } + + /** Minings the block if it is possible. */ + public void mineBlock(IGregTechTileEntity te, Block block, int x, int y, int z) { + if (!GT_Utility.eraseBlockByFakePlayer(getFakePlayer(te), x, y, z, true)) { + return; + } + + List<ItemStack> drops = getBlockDrops(block, x, y, z); + + boolean canFitDrops = true; + for (ItemStack drop : drops) { + canFitDrops &= owner.pushOutputs(drop, drop.stackSize, true, false); + } + if (!canFitDrops) { + return; + } + for (ItemStack drop : drops) { + owner.pushOutputs(drop, drop.stackSize, false, false); + } + + short metaData = 0; + TileEntity tTileEntity = owner.getBaseMetaTileEntity().getTileEntity(x, y, z); + if (tTileEntity instanceof GT_TileEntity_Ores) { + metaData = ((GT_TileEntity_Ores)tTileEntity).mMetaData; + } + + ItemStack cobble = GT_Utility.getCobbleForOre(block, metaData); + te.getWorld().setBlock(x, y, z, Block.getBlockFromItem(cobble.getItem()), cobble.getItemDamage(), /*cause updates(1) + send to client(2)*/ 3); + } + + /** Returns NEGATIVE (eg -5) depth of current drilling Y world level. RELATIVELY TO MINER ENTITY! This means '(miner world Y) + depth = (actual world Y)'. */ + public int getTipDepth() { + return tipDepth; + } + + /** Looking for the lowest continuous pipe. */ + public void findTipDepth() { + IGregTechTileEntity ownerTe = owner.getBaseMetaTileEntity(); + if (!ownerTe.isServerSide()) { + return; + } + while (true) { + Block block = ownerTe.getBlockOffset(0, tipDepth - 1, 0); + if (block != MINING_PIPE_BLOCK && block != MINING_PIPE_TIP_BLOCK) { + return; + } + tipDepth--; + } + } + + /** Creates and provides the Fake Player for owners. todo maybe will provide player owner uuid? im sure some servers not allow to fakers, in griefing reasons. */ + public FakePlayer getFakePlayer(IGregTechTileEntity te) { + if (mFakePlayer == null) { + mFakePlayer = GT_Utility.getFakePlayer(te); + } + if (mFakePlayer != null) { + mFakePlayer.setWorld(te.getWorld()); + mFakePlayer.setPosition(te.getXCoord(), te.getYCoord(), te.getZCoord()); + } + return mFakePlayer; + } + + public boolean canFakePlayerInteract(IGregTechTileEntity te, int xCoord, int yCoord, int zCoord) { + return GT_Utility.setBlockByFakePlayer(getFakePlayer(te), xCoord, yCoord, zCoord, MINING_PIPE_TIP_BLOCK, 0, true); + } + + /** Get target block drops. We need to encapsulate everyting of mining in this class. */ + private List<ItemStack> getBlockDrops(final Block oreBlock, int posX, int posY, int posZ) { + return oreBlock.getDrops(owner.getBaseMetaTileEntity().getWorld(), posX, posY, posZ, owner.getBaseMetaTileEntity().getMetaID(posX, posY, posZ), owner.getMachineTier()); + } + + /** Can the owner continue doing its work? If we await new pipes - it cannot. */ + public boolean canContinueDrilling(long tick) { + if (isWaitingForPipeItem) { + if (tick % 5 != 0) { + return false; + } + boolean hasPipe = owner.pullInputs(MINING_PIPE_STACK.getItem(), 1, true); + if (hasPipe) { + isWaitingForPipeItem = false; + } + return hasPipe; + } + return true; + } +} diff --git a/src/main/java/gregtech/common/misc/GT_IDrillingLogicDelegateOwner.java b/src/main/java/gregtech/common/misc/GT_IDrillingLogicDelegateOwner.java new file mode 100644 index 0000000000..f290e8ac8c --- /dev/null +++ b/src/main/java/gregtech/common/misc/GT_IDrillingLogicDelegateOwner.java @@ -0,0 +1,21 @@ +package gregtech.common.misc; + +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +/** @author Relvl on 27.01.2022 */ +public interface GT_IDrillingLogicDelegateOwner extends IMetaTileEntity { + + /** Returns the machine actual tier. */ + int getMachineTier(); + + /** Returns the machine current processing speed. */ + int getMachineSpeed(); + + /** Pulls (or check can pull) items from an input slots. */ + boolean pullInputs(Item item, int count, boolean simulate); + + /** Pushes (or check can push) item to output slots. */ + boolean pushOutputs(ItemStack stack, int count, boolean simulate, boolean allowInputSlots); +} diff --git a/src/main/java/gregtech/common/tileentities/machines/basic/GT_MetaTileEntity_Miner.java b/src/main/java/gregtech/common/tileentities/machines/basic/GT_MetaTileEntity_Miner.java index a11ab7fa41..cf3ed75291 100644 --- a/src/main/java/gregtech/common/tileentities/machines/basic/GT_MetaTileEntity_Miner.java +++ b/src/main/java/gregtech/common/tileentities/machines/basic/GT_MetaTileEntity_Miner.java @@ -1,5 +1,7 @@ package gregtech.common.tileentities.machines.basic; +import java.util.ArrayList; + import gregtech.api.enums.Textures; import gregtech.api.interfaces.ITexture; import gregtech.api.interfaces.metatileentity.IMetaTileEntity; @@ -7,13 +9,14 @@ import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachine; import gregtech.api.render.TextureFactory; import gregtech.api.util.GT_Log; -import gregtech.api.util.GT_ModHandler; import gregtech.api.util.GT_Utility; import gregtech.common.blocks.GT_Block_Ores_Abstract; import gregtech.common.blocks.GT_TileEntity_Ores; +import gregtech.common.misc.GT_IDrillingLogicDelegateOwner; +import gregtech.common.misc.GT_DrillingLogicDelegate; import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.Blocks; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; @@ -21,75 +24,85 @@ import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.StatCollector; import net.minecraft.world.ChunkPosition; import net.minecraftforge.common.util.FakePlayer; - -import java.util.ArrayList; - import static gregtech.api.enums.GT_Values.V; import static gregtech.api.enums.GT_Values.debugBlockMiner; -public class GT_MetaTileEntity_Miner extends GT_MetaTileEntity_BasicMachine { - private static final ItemStack MINING_PIPE = GT_ModHandler.getIC2Item("miningPipe", 0); - private static final Block MINING_PIPE_BLOCK = GT_Utility.getBlockFromStack(MINING_PIPE); - private static final Block MINING_PIPE_TIP_BLOCK = GT_Utility.getBlockFromStack(GT_ModHandler.getIC2Item("miningPipeTip", 0)); - - int drillY = 0; - boolean mRetractDone; - - boolean waitMiningPipe; +@SuppressWarnings("ObjectEquality") +public class GT_MetaTileEntity_Miner extends GT_MetaTileEntity_BasicMachine implements GT_IDrillingLogicDelegateOwner { static final int[] RADIUS = {8, 8, 16, 24, 32}; //Miner radius per tier static final int[] SPEED = {160, 160, 80, 40, 20}; //Miner cycle time per tier static final int[] ENERGY = {8, 8, 32, 128, 512}; //Miner energy consumption per tier - private int radiusConfig; //Miner configured radius + /** Miner configured radius */ + private int radiusConfig; + /** Found ore blocks cache of current drill depth */ private final ArrayList<ChunkPosition> oreBlockPositions = new ArrayList<>(); + /** General pipe accessor */ + private final GT_DrillingLogicDelegate pipe = new GT_DrillingLogicDelegate(this); + private final int mSpeed; + public GT_MetaTileEntity_Miner(int aID, String aName, String aNameRegional, int aTier) { super(aID, aName, aNameRegional, aTier, 1, - new String[]{ - "Digging ore instead of you", - "Use Screwdriver to regulate work area", - "Use Soft Mallet to disable and retract the pipe", - ENERGY[aTier] + " EU/t, " + SPEED[aTier] / 20 + " sec per block, no stuttering", - "Maximum work area " + (RADIUS[aTier] * 2 + 1) + "x" + (RADIUS[aTier] * 2 + 1), - "Fortune bonus of " + aTier}, - 2, 2, "Miner.png", "", - TextureFactory.of( - TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_SIDE_ACTIVE")), - TextureFactory.builder().addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_SIDE_ACTIVE_GLOW")).glow().build()), - TextureFactory.of( - TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_SIDE")), - TextureFactory.builder().addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_SIDE_GLOW")).glow().build()), - TextureFactory.of( - TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_FRONT_ACTIVE")), - TextureFactory.builder().addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_FRONT_ACTIVE_GLOW")).glow().build()), - TextureFactory.of( - TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_FRONT")), - TextureFactory.builder().addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_FRONT_GLOW")).glow().build()), - TextureFactory.of( - TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_TOP_ACTIVE")), - TextureFactory.builder().addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_TOP_ACTIVE_GLOW")).glow().build()), - TextureFactory.of( - TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_TOP")), - TextureFactory.builder().addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_TOP_GLOW")).glow().build()), - TextureFactory.of( - TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_BOTTOM_ACTIVE")), - TextureFactory.builder().addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_BOTTOM_ACTIVE_GLOW")).glow().build()), - TextureFactory.of( - TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_BOTTOM")), - TextureFactory.builder().addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_BOTTOM_GLOW")).glow().build()) - ); + new String[]{ + "Digging ore instead of you", + "Use Screwdriver to regulate work area", + "Use Soft Mallet to disable and retract the pipe", + String.format("%d EU/t, %d sec per block, no stuttering", ENERGY[aTier], SPEED[aTier] / 20), + String.format("Maximum work area %dx%d", (RADIUS[aTier] * 2 + 1), (RADIUS[aTier] * 2 + 1)), + String.format("Fortune bonus of %d", aTier) + }, + 2, + 2, + "Miner.png", + "", + TextureFactory.of( + TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_SIDE_ACTIVE")), + TextureFactory.builder().addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_SIDE_ACTIVE_GLOW")).glow().build() + ), + TextureFactory.of( + TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_SIDE")), + TextureFactory.builder().addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_SIDE_GLOW")).glow().build() + ), + TextureFactory.of( + TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_FRONT_ACTIVE")), + TextureFactory.builder().addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_FRONT_ACTIVE_GLOW")).glow().build() + ), + TextureFactory.of( + TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_FRONT")), + TextureFactory.builder().addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_FRONT_GLOW")).glow().build() + ), + TextureFactory.of( + TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_TOP_ACTIVE")), + TextureFactory.builder().addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_TOP_ACTIVE_GLOW")).glow().build() + ), + TextureFactory.of( + TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_TOP")), + TextureFactory.builder().addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_TOP_GLOW")).glow().build() + ), + TextureFactory.of( + TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_BOTTOM_ACTIVE")), + TextureFactory.builder().addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_BOTTOM_ACTIVE_GLOW")).glow().build() + ), + TextureFactory.of( + TextureFactory.of(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_BOTTOM")), + TextureFactory.builder().addIcon(new Textures.BlockIcons.CustomIcon("basicmachines/miner/OVERLAY_BOTTOM_GLOW")).glow().build() + ) + ); + mSpeed = SPEED[aTier]; radiusConfig = RADIUS[mTier]; -} + } public GT_MetaTileEntity_Miner(String aName, int aTier, String aDescription, ITexture[][][] aTextures, String aGUIName, String aNEIName) { super(aName, aTier, 1, aDescription, aTextures, 1, 1, aGUIName, aNEIName); + mSpeed = SPEED[aTier]; radiusConfig = RADIUS[mTier]; -} + } public GT_MetaTileEntity_Miner(String aName, int aTier, String[] aDescription, ITexture[][][] aTextures, String aGUIName, String aNEIName) { super(aName, aTier, 1, aDescription, aTextures, 2, 2, aGUIName, aNEIName); + mSpeed = SPEED[aTier]; radiusConfig = RADIUS[mTier]; - } @Override @@ -98,10 +111,18 @@ public class GT_MetaTileEntity_Miner extends GT_MetaTileEntity_BasicMachine { } @Override + public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) { + pipe.findTipDepth(); + fillOreList(aBaseMetaTileEntity); + } + + @Override protected boolean allowPutStackValidated(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, byte aSide, ItemStack aStack) { - return super.allowPutStackValidated(aBaseMetaTileEntity, aIndex, aSide, aStack) && aStack.getItem() == MINING_PIPE.getItem(); + return super.allowPutStackValidated(aBaseMetaTileEntity, aIndex, aSide, aStack) // + && aStack.getItem() == GT_DrillingLogicDelegate.MINING_PIPE_STACK.getItem(); } + /** Both output slots must be free to work */ public boolean hasFreeSpace() { for (int i = getOutputSlot(); i < getOutputSlot() + 2; i++) { if (mInventory[i] != null) { @@ -119,24 +140,28 @@ public class GT_MetaTileEntity_Miner extends GT_MetaTileEntity_BasicMachine { if (radiusConfig >= 0) { radiusConfig--; } - if (radiusConfig < 0) + if (radiusConfig < 0) { radiusConfig = RADIUS[mTier]; - } else { + } + } + else { if (radiusConfig <= RADIUS[mTier]) { radiusConfig++; } - if (radiusConfig > RADIUS[mTier]) + if (radiusConfig > RADIUS[mTier]) { radiusConfig = 0; + } } - GT_Utility.sendChatToPlayer(aPlayer, StatCollector.translateToLocal("GT5U.machines.workareaset") + " " + (radiusConfig * 2 + 1) + "x" + (radiusConfig * 2 + 1));//TODO Add translation support - oreBlockPositions.clear(); + + GT_Utility.sendChatToPlayer( + aPlayer, + String.format("%s %dx%d", StatCollector.translateToLocal("GT5U.machines.workareaset"), (radiusConfig * 2 + 1), (radiusConfig * 2 + 1)) + ); + + // Rebuild ore cache after change config fillOreList(getBaseMetaTileEntity()); } } - @Override - public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) { - fillOreList(aBaseMetaTileEntity); - } @Override public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { @@ -145,281 +170,213 @@ public class GT_MetaTileEntity_Miner extends GT_MetaTileEntity_BasicMachine { if (!aBaseMetaTileEntity.isServerSide()) { return; } - // If the machine was disabled - try to retract pipe - if (!aBaseMetaTileEntity.isAllowedToWork()){ + + // Pipe workaround + pipe.onOwnerPostTick(aBaseMetaTileEntity, aTick); + + if (!aBaseMetaTileEntity.isAllowedToWork()) { mMaxProgresstime = 0; - onPostTickRetract(aBaseMetaTileEntity, aTick); + if (debugBlockMiner) { + GT_Log.out.println("MINER: Disabled"); + } return; } - // If the machine was re-enabled - we should reset the retracting process - mRetractDone = false; - - boolean hasFreeSpace = hasFreeSpace(); - boolean hasEnergy = aBaseMetaTileEntity.isUniversalEnergyStored(ENERGY[mTier] * (SPEED[mTier] - mProgresstime)); - if (!hasEnergy || !hasFreeSpace){ + if (!hasFreeSpace()) { mMaxProgresstime = 0; if (debugBlockMiner) { - if (!aBaseMetaTileEntity.isAllowedToWork()) { - GT_Log.out.println("MINER: Disabled"); - } - if (!hasEnergy) { - GT_Log.out.println("MINER: Not enough energy yet, want " + (ENERGY[mTier] * SPEED[mTier]) + " have " + aBaseMetaTileEntity.getUniversalEnergyStored()); - } - if (!hasFreeSpace) { - GT_Log.out.println("MINER: No free space"); - } + GT_Log.out.println("MINER: No free space"); } return; } - ItemStack minigPipeStack = getMiningPipe(0); - if (waitMiningPipe){ - if (minigPipeStack == null || minigPipeStack.stackSize == 0){ - mMaxProgresstime = 0; - if (debugBlockMiner){ - GT_Log.out.println("MINER: Pipe found in input"); - } - return; + if (!aBaseMetaTileEntity.isUniversalEnergyStored((long)ENERGY[mTier] * (mSpeed - mProgresstime))) { + mMaxProgresstime = 0; + if (debugBlockMiner) { + GT_Log.out.println("MINER: Not enough energy yet, want " + (ENERGY[mTier] * mSpeed) + " have " + aBaseMetaTileEntity.getUniversalEnergyStored()); } + return; + } + + /* Checks if machine are waiting new mining pipe item */ + if (!pipe.canContinueDrilling(aTick)) { + mMaxProgresstime = 0; + return; } + mMaxProgresstime = mSpeed; + aBaseMetaTileEntity.decreaseStoredEnergyUnits(ENERGY[mTier], true); - mMaxProgresstime = SPEED[mTier]; - - if (mProgresstime == SPEED[mTier] - 1) { - if (drillY == 0 || oreBlockPositions.isEmpty()) { - moveOneDown(aBaseMetaTileEntity); - } else { - ChunkPosition oreBlockPos; - int x = 0, y = 0, z = 0; + + // Real working only when progress done. TODO some legacy code... refactorings needed + if (mProgresstime == mSpeed - 1) { + if (pipe.getTipDepth() == 0 || oreBlockPositions.isEmpty()) { + boolean descends = pipe.descent(aBaseMetaTileEntity); + if (descends) { + fillOreList(aBaseMetaTileEntity); + } + } + else { + int x; + int y; + int z; Block oreBlock; - int oreBlockMetadata = 0; + boolean isOre; do { - oreBlockPos = oreBlockPositions.remove(0); + ChunkPosition oreBlockPos = oreBlockPositions.remove(0); oreBlock = aBaseMetaTileEntity.getBlockOffset(oreBlockPos.chunkPosX, oreBlockPos.chunkPosY, oreBlockPos.chunkPosZ); x = aBaseMetaTileEntity.getXCoord() + oreBlockPos.chunkPosX; y = aBaseMetaTileEntity.getYCoord() + oreBlockPos.chunkPosY; z = aBaseMetaTileEntity.getZCoord() + oreBlockPos.chunkPosZ; - oreBlockMetadata = getBaseMetaTileEntity().getWorld().getBlockMetadata(x, y, z); + isOre = GT_Utility.isOre(oreBlock, aBaseMetaTileEntity.getWorld().getBlockMetadata(x, y, z)); } // someone else might have removed the block - while (!GT_Utility.isOre(oreBlock, oreBlockMetadata) && !oreBlockPositions.isEmpty()); + while (!isOre && !oreBlockPositions.isEmpty()); - if (GT_Utility.isOre(oreBlock, oreBlockMetadata)) { - mineBlock(aBaseMetaTileEntity, oreBlock, x, y, z); + if (isOre) { + pipe.mineBlock(aBaseMetaTileEntity, oreBlock, x, y, z); } } } } - /** - * If the machine are disabled - tried to retract pipe - */ - private void onPostTickRetract(IGregTechTileEntity aBaseMetaTileEntity, long aTick) { - if (mRetractDone) { - return; - } - // If retracting process just touch the miner - if (drillY == 0) { - mRetractDone = true; - return; - } - // Once per N ticks (depends on tier) - if ((aTick % (SPEED[mTier] / 5)) != 0) { - return; - } - // Check the pipe fits the first output slot - int outSlotIndex = getOutputSlot(); - ItemStack outSlotItem = this.mInventory[outSlotIndex]; - if (outSlotItem != null && !GT_Utility.areStacksEqual(outSlotItem, MINING_PIPE)) { - return; - } - // Inspect target block - it should be a pipe tip, else something went wrong. - Block inspectedBlock = aBaseMetaTileEntity.getBlockOffset(0, drillY, 0); - boolean isPipeTip = inspectedBlock == MINING_PIPE_TIP_BLOCK; - if (!isPipeTip) { + /** Finds the ores in current drill Y level */ + private void fillOreList(IGregTechTileEntity aBaseMetaTileEntity) { + if (pipe.getTipDepth() == 0) { return; } - // Retract the pipe/tip - int xCoord = aBaseMetaTileEntity.getXCoord(); - int yCoord = aBaseMetaTileEntity.getYCoord(); - int zCoord = aBaseMetaTileEntity.getZCoord(); - int actualDrillY = yCoord + drillY; - // Move the pipe tip position - if (actualDrillY < yCoord - 1) { - getBaseMetaTileEntity().getWorld().setBlock(xCoord, actualDrillY + 1, zCoord, MINING_PIPE_TIP_BLOCK); - } - // Remove the old pipe tip - aBaseMetaTileEntity.getWorld().setBlockToAir(xCoord, actualDrillY, zCoord); - // Return the pipe into the machine - if (outSlotItem == null) { - final ItemStack copy = MINING_PIPE.copy(); - copy.stackSize = 1; - this.setInventorySlotContents(outSlotIndex, copy); - } else { - this.mInventory[outSlotIndex].stackSize++; + oreBlockPositions.clear(); + for (int z = -radiusConfig; z <= radiusConfig; ++z) { + for (int x = -radiusConfig; x <= radiusConfig; ++x) { + Block block = aBaseMetaTileEntity.getBlockOffset(x, pipe.getTipDepth(), z); + int blockMeta = aBaseMetaTileEntity.getMetaIDOffset(x, pipe.getTipDepth(), z); + + // todo some weird checks. refactorings needed + if (block instanceof GT_Block_Ores_Abstract) { + TileEntity oreEntity = aBaseMetaTileEntity.getTileEntityOffset(x, pipe.getTipDepth(), z); + if (oreEntity instanceof GT_TileEntity_Ores && ((GT_TileEntity_Ores)oreEntity).mNatural) { + oreBlockPositions.add(new ChunkPosition(x, pipe.getTipDepth(), z)); + } + } + else if (GT_Utility.isOre(block, blockMeta)) { + oreBlockPositions.add(new ChunkPosition(x, pipe.getTipDepth(), z)); + } + } } - drillY++; } - /** - * Returns first available pipe from input slots - */ - private ItemStack getMiningPipe(int modify) { + /** Pulls (or check can pull) items from an input slots. */ + @Override + public boolean pullInputs(Item item, int count, boolean simulate) { for (int i = 0; i < mInputSlotCount; i++) { ItemStack stack = getInputAt(i); - if (stack != null && stack.getItem() == MINING_PIPE.getItem() && stack.stackSize > 0) { - stack.stackSize += modify; + if (stack != null && stack.getItem() == item && stack.stackSize >= count) { + if (simulate) { + return true; + } + stack.stackSize -= count; if (stack.stackSize == 0) { mInventory[getInputSlot() + i] = null; } - return stack; + return true; } } - return null; + return false; } - /** - * Findsw the ores in current drill Y level - */ - private void fillOreList(IGregTechTileEntity aBaseMetaTileEntity) { - if (drillY == 0) - return; - for (int z = -radiusConfig; z <= radiusConfig; ++z) { - for (int x = -radiusConfig; x <= radiusConfig; ++x) { - Block block = aBaseMetaTileEntity.getBlockOffset(x, drillY, z); - int blockMeta = aBaseMetaTileEntity.getMetaIDOffset(x, drillY, z); - if (block instanceof GT_Block_Ores_Abstract) { - TileEntity tTileEntity = getBaseMetaTileEntity().getTileEntityOffset(x, drillY, z); - if (tTileEntity instanceof GT_TileEntity_Ores && ((GT_TileEntity_Ores) tTileEntity).mNatural) - oreBlockPositions.add(new ChunkPosition(x, drillY, z)); - } else if (GT_Utility.isOre(block, blockMeta)) - oreBlockPositions.add(new ChunkPosition(x, drillY, z)); - } - } - } + /** Pushes (or check can push) item to output slots. */ @Override - public long maxEUStore() { - return mTier == 1 ? 4096 : V[mTier] * 64; - } - - public boolean moveOneDown(IGregTechTileEntity aBaseMetaTileEntity) { - int xCoord = aBaseMetaTileEntity.getXCoord(); - int zCoord = aBaseMetaTileEntity.getZCoord(); - int yCoord = aBaseMetaTileEntity.getYCoord(); - boolean isHitsTheVoid = yCoord + drillY - 1 < 0; - boolean isHitsBedrock = GT_Utility.getBlockHardnessAt(aBaseMetaTileEntity.getWorld(), xCoord, yCoord + drillY - 1, zCoord) < 0; - boolean isFakePlayerAllowed = GT_Utility.setBlockByFakePlayer(getFakePlayer(aBaseMetaTileEntity), xCoord, yCoord + drillY - 1, zCoord, MINING_PIPE_TIP_BLOCK, 0, true); - - if (isHitsTheVoid || isHitsBedrock || !isFakePlayerAllowed) { - aBaseMetaTileEntity.disableWorking(); - if (debugBlockMiner) { - if (isHitsTheVoid) { - GT_Log.out.println("MINER: Hit bottom"); - } - if (isHitsBedrock) { - GT_Log.out.println("MINER: Hit block with -1 hardness"); - } - if (!isFakePlayerAllowed) { - GT_Log.out.println("MINER: Unable to set mining pipe tip"); + public boolean pushOutputs(ItemStack stack, int count, boolean simulate, boolean allowInputSlots) { + int startSlot = allowInputSlots ? getInputSlot() : getOutputSlot(); + int maxSlot = mInventory.length; + for (int i = startSlot; i < maxSlot; i++) { + ItemStack slot = mInventory[i]; + if (slot == null || slot.stackSize == 0) { + if (!simulate) { + ItemStack copy = stack.copy(); + copy.stackSize = count; + mInventory[i] = copy; } + return true; } - return false; - } - // Replace the tip onto pipe - if (aBaseMetaTileEntity.getBlockOffset(0, drillY, 0) == MINING_PIPE_TIP_BLOCK) { - aBaseMetaTileEntity.getWorld().setBlock(xCoord, yCoord + drillY, zCoord, MINING_PIPE_BLOCK); - } - // Get and decrease pipe from the machine - ItemStack pipeInSlot = getMiningPipe(-1); - if (pipeInSlot == null) { - // If there was nothing - wainting for the pipes (just for prevent unnecessary checks) - waitMiningPipe = true; - return false; - } - // If there is something - mine it (todo don't matter what? maybe some checks like in mining method?) - Block block = aBaseMetaTileEntity.getBlockOffset(0, drillY - 1, 0); - if (block != Blocks.air) { - mineBlock(aBaseMetaTileEntity, block, xCoord, yCoord + drillY - 1, zCoord); - } - // Raise the pipe tip - aBaseMetaTileEntity.getWorld().setBlock(xCoord, yCoord + drillY - 1, zCoord, MINING_PIPE_TIP_BLOCK); - drillY--; - fillOreList(aBaseMetaTileEntity); - return true; - } - - public void mineBlock(IGregTechTileEntity aBaseMetaTileEntity, Block block, int x, int y, int z) { - if (!GT_Utility.eraseBlockByFakePlayer(getFakePlayer(aBaseMetaTileEntity), x, y, z, true)) { - if (debugBlockMiner) - GT_Log.out.println("MINER: FakePlayer cannot mine block at " + x + ", " + y + ", " + z); - } else { - ArrayList<ItemStack> drops = getBlockDrops(block, x, y, z); - if (drops.size() > 0) - mOutputItems[0] = drops.get(0); - if (drops.size() > 1) - mOutputItems[1] = drops.get(1); - - short metaData = 0; - TileEntity tTileEntity = getBaseMetaTileEntity().getTileEntity(x, y, z); - if (tTileEntity instanceof GT_TileEntity_Ores) { - metaData = ((GT_TileEntity_Ores) tTileEntity).mMetaData; + else if (GT_Utility.areStacksEqual(slot, stack) && slot.stackSize <= slot.getMaxStackSize() - count) { + if (!simulate) { + slot.stackSize += count; + } + return true; } - - ItemStack cobble = GT_Utility.getCobbleForOre(block, metaData); - aBaseMetaTileEntity.getWorld().setBlock(x, y, z, Block.getBlockFromItem(cobble.getItem()), cobble.getItemDamage(), 3); - if (debugBlockMiner) - GT_Log.out.println("MINER: Mining GT ore block at " + x + " " + y + " " + z); } + return false; } - private ArrayList<ItemStack> getBlockDrops(final Block oreBlock, int posX, int posY, int posZ) { - final int blockMeta = getBaseMetaTileEntity().getMetaID(posX, posY, posZ); - return oreBlock.getDrops(getBaseMetaTileEntity().getWorld(), posX, posY, posZ, blockMeta, mTier); + @Override + public long maxEUStore() { + return Math.max(V[mTier] * 64, 4096); } @Override public void setItemNBT(NBTTagCompound aNBT) { super.setItemNBT(aNBT); - aNBT.setByte("mTier", mTier); aNBT.setInteger("radiusConfig", radiusConfig); } @Override public void saveNBTData(NBTTagCompound aNBT) { super.saveNBTData(aNBT); - aNBT.setInteger("drillY", drillY); aNBT.setInteger("radiusConfig", radiusConfig); } @Override public void loadNBTData(NBTTagCompound aNBT) { super.loadNBTData(aNBT); - // todo actually we need to find pipes from the 0Y in the up direction until the miner, and don't need to save it - drillY = aNBT.getInteger("drillY"); - if (aNBT.hasKey("radiusConfig")) - radiusConfig = aNBT.getInteger("radiusConfig"); - } - - private FakePlayer mFakePlayer = null; - - protected FakePlayer getFakePlayer(IGregTechTileEntity aBaseTile) { - if (mFakePlayer == null) - mFakePlayer = GT_Utility.getFakePlayer(aBaseTile); - if (mFakePlayer != null) { - mFakePlayer.setWorld(aBaseTile.getWorld()); - mFakePlayer.setPosition(aBaseTile.getXCoord(), aBaseTile.getYCoord(), aBaseTile.getZCoord()); + if (aNBT.hasKey("radiusConfig")) { + int newRadius = aNBT.getInteger("radiusConfig"); + if (RADIUS[mTier] <= newRadius && newRadius > 0) { + radiusConfig = newRadius; + } } - return mFakePlayer; } @Override public String[] getInfoData() { return new String[]{ - EnumChatFormatting.BLUE+StatCollector.translateToLocal("GT5U.machines.miner")+EnumChatFormatting.RESET, - StatCollector.translateToLocal("GT5U.machines.workarea")+": " + EnumChatFormatting.GREEN + (radiusConfig * 2 + 1)+ - EnumChatFormatting.RESET+" " + StatCollector.translateToLocal("GT5U.machines.blocks") + String.format("%s%s%s", EnumChatFormatting.BLUE, StatCollector.translateToLocal("GT5U.machines.miner"), EnumChatFormatting.RESET), + String.format("%s: %s%d%s %s", + StatCollector.translateToLocal("GT5U.machines.workarea"), + EnumChatFormatting.GREEN, + (radiusConfig * 2 + 1), + EnumChatFormatting.RESET, + StatCollector.translateToLocal("GT5U.machines.blocks") + ) }; } + @Override + public int getMachineTier() { + return mTier; + } + + @Override + public int getMachineSpeed() { + return mSpeed; + } + + /** @deprecated This method are obsolete, and may be removed in further updates. Please use 'this.getPipe().descent()' access! */ + @Deprecated + public boolean moveOneDown(IGregTechTileEntity tileEntity) { + boolean descends = pipe.descent(tileEntity); + if (descends) { + fillOreList(tileEntity); + } + return descends; + } + + /** @deprecated This method are obsolete, and may be removed in further updates. Please use 'this.getPipe().getFakePlayer(te)' access! */ + @Deprecated + protected FakePlayer getFakePlayer(IGregTechTileEntity aBaseTile) { + return pipe.getFakePlayer(aBaseTile); + } + + public GT_DrillingLogicDelegate getPipe() { + return pipe; + } } |