diff options
Diffstat (limited to 'src/main/java/gregtech/common/misc')
23 files changed, 4176 insertions, 0 deletions
diff --git a/src/main/java/gregtech/common/misc/GT_ClientPollutionMap.java b/src/main/java/gregtech/common/misc/GT_ClientPollutionMap.java new file mode 100644 index 0000000000..6e40e5860c --- /dev/null +++ b/src/main/java/gregtech/common/misc/GT_ClientPollutionMap.java @@ -0,0 +1,140 @@ +package gregtech.common.misc; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityClientPlayerMP; +import net.minecraft.util.MathHelper; + +public class GT_ClientPollutionMap { + + private static final byte RADIUS = 24; + private static final byte DISTANCE_RELOAD_MAP = 5; // When player moved x chunks, shift the map to new center. + private static final byte SIZE = RADIUS * 2 + 1; // Area to keep stored. + + private int x0, z0; + private int dim; + + private boolean initialized = false; + + private static short[][] chunkMatrix; // short because reasons. + + public GT_ClientPollutionMap() {} + + public void reset() { + initialized = false; + } + + private void initialize(int playerChunkX, int playerChunkZ, int dimension) { + initialized = true; + chunkMatrix = new short[SIZE][SIZE]; + x0 = playerChunkX; + z0 = playerChunkZ; + dim = dimension; + } + + public void addChunkPollution(int chunkX, int chunkZ, int pollution) { + EntityClientPlayerMP player = Minecraft.getMinecraft().thePlayer; + if (player == null || player.worldObj == null) return; + + int playerXChunk = MathHelper.floor_double(player.posX) >> 4; + int playerZChunk = MathHelper.floor_double(player.posZ) >> 4; // posX/Z seems to be always loaded, + + if (!initialized) { + initialize(playerXChunk, playerZChunk, player.dimension); + } + + if (dim != player.dimension) { + initialize(playerXChunk, playerZChunk, player.dimension); + } + + if (Math.abs(x0 - playerXChunk) > DISTANCE_RELOAD_MAP || Math.abs(z0 - playerZChunk) > DISTANCE_RELOAD_MAP) + shiftCenter(playerXChunk, playerZChunk); + + int relX = chunkX - x0 + RADIUS; + if (relX >= SIZE || relX < 0) // out of bounds + return; + int relZ = chunkZ - z0 + RADIUS; + if (relZ >= SIZE || relZ < 0) // out of bounds + return; + + pollution = pollution / 225; + if (pollution > Short.MAX_VALUE) // Sanity + chunkMatrix[relX][relZ] = Short.MAX_VALUE; // Max pollution = 7,3mill + else if (pollution < 0) chunkMatrix[relX][relZ] = 0; + else chunkMatrix[relX][relZ] = (short) (pollution); + } + + // xy interpolation, between 4 chunks as corners, unknown treated as 0. + public int getPollution(double fx, double fz) { + if (!initialized) return 0; + int x = MathHelper.floor_double(fx); + int z = MathHelper.floor_double(fz); + int xDiff = ((x - 8) >> 4) - x0; + int zDiff = ((z - 8) >> 4) - z0; + + if (xDiff < -RADIUS || zDiff < -RADIUS || xDiff >= RADIUS || zDiff >= RADIUS) return 0; + + // coordinates in shifted chunk. + x = (x - 8) % 16; + z = (z - 8) % 16; + if (x < 0) x = 16 + x; + if (z < 0) z = 16 + z; + + int xi = 15 - x; + int zi = 15 - z; + + // read pollution in 4 corner chunks + int offsetX = RADIUS + xDiff; + int offsetZ = RADIUS + zDiff; + + int c00 = chunkMatrix[offsetX][offsetZ]; + int c10 = chunkMatrix[offsetX + 1][offsetZ]; + int c01 = chunkMatrix[offsetX][offsetZ + 1]; + int c11 = chunkMatrix[offsetX + 1][offsetZ + 1]; + + // Is divided by 15*15 but is handled when storing chunk data. + return c00 * xi * zi + c10 * x * zi + c01 * xi * z + c11 * x * z; + } + + // shift the matrix to fit new center + private void shiftCenter(int chunkX, int chunkZ) { + int xDiff = chunkX - x0; + int zDiff = chunkZ - z0; + boolean[] allEmpty = new boolean[SIZE]; // skip check z row if its empty. + if (xDiff > 0) for (byte x = 0; x < SIZE; x++) { + int xOff = x + xDiff; + if (xOff < SIZE) { + chunkMatrix[x] = chunkMatrix[xOff].clone(); + } else { + chunkMatrix[x] = new short[SIZE]; + allEmpty[x] = true; + } + } + else if (xDiff < 0) for (byte x = SIZE - 1; x >= 0; x--) { + int xOff = x + xDiff; + if (xOff > 0) { + chunkMatrix[x] = chunkMatrix[xOff].clone(); + } else { + chunkMatrix[x] = new short[SIZE]; + allEmpty[x] = true; + } + } + + if (zDiff > 0) for (byte x = 0; x < SIZE; x++) { + if (allEmpty[x]) continue; + for (int z = 0; z < SIZE; z++) { + int zOff = z + zDiff; + chunkMatrix[x][z] = (zOff < SIZE) ? chunkMatrix[x][zOff] : 0; + } + } + else if (zDiff < 0) for (byte x = 0; x < SIZE; x++) { + if (allEmpty[x]) continue; + for (int z = SIZE - 1; z >= 0; z--) { + int zOff = z + zDiff; + chunkMatrix[x][z] = (zOff > 0) ? chunkMatrix[x][zOff] : 0; + } + } + + x0 = chunkX; + z0 = chunkZ; + } +} diff --git a/src/main/java/gregtech/common/misc/GT_Command.java b/src/main/java/gregtech/common/misc/GT_Command.java new file mode 100644 index 0000000000..8e342aa928 --- /dev/null +++ b/src/main/java/gregtech/common/misc/GT_Command.java @@ -0,0 +1,355 @@ +package gregtech.common.misc; + +import static gregtech.common.misc.WirelessNetworkManager.addEUToGlobalEnergyMap; +import static gregtech.common.misc.WirelessNetworkManager.getUserEU; +import static gregtech.common.misc.WirelessNetworkManager.setUserEU; + +import java.lang.reflect.Field; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.stream.Stream; + +import net.minecraft.command.CommandBase; +import net.minecraft.command.ICommandSender; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.EnumChatFormatting; + +import com.gtnewhorizon.structurelib.StructureLib; + +import cpw.mods.fml.relauncher.FMLLaunchHandler; +import gregtech.GT_Mod; +import gregtech.api.enums.GT_Values; +import gregtech.api.objects.GT_ChunkManager; +import gregtech.api.util.GT_MusicSystem; +import gregtech.api.util.GT_Utility; +import gregtech.common.GT_Pollution; +import gregtech.common.misc.spaceprojects.SpaceProjectManager; + +public final class GT_Command extends CommandBase { + + @Override + public String getCommandName() { + return "gt"; + } + + @Override + public String getCommandUsage(ICommandSender sender) { + return "Usage: gt <subcommand>. Valid subcommands are: toggle, chunks, pollution, global_energy_add, global_energy_set, global_energy_join, dump_music_durations."; + } + + private void printHelp(ICommandSender sender) { + sender.addChatMessage( + new ChatComponentText( + "Usage: gt <toggle|chunks|pollution|global_energy_add|global_energy_set|global_energy_join|dump_music_durations>")); + sender.addChatMessage(new ChatComponentText("\"toggle D1\" - toggles general.Debug (D1)")); + sender.addChatMessage(new ChatComponentText("\"toggle D2\" - toggles general.Debug2 (D2)")); + sender.addChatMessage(new ChatComponentText("\"toggle debugCleanroom\" - toggles cleanroom debug log")); + sender.addChatMessage(new ChatComponentText("\"toggle debugDriller\" - toggles oil drill debug log")); + sender.addChatMessage(new ChatComponentText("\"toggle debugBlockPump\" - Possible issues with pumps")); + sender.addChatMessage(new ChatComponentText("\"toggle debugBlockMiner\" - Possible issues with miners")); + sender.addChatMessage( + new ChatComponentText("\"toggle debugEntityCramming\" - How long it takes and how many entities it finds")); + sender.addChatMessage(new ChatComponentText("\"toggle debugWorldGen\" - toggles generic worldgen debug")); + sender.addChatMessage(new ChatComponentText("\"toggle debugOrevein\" - toggles worldgen ore vein debug")); + sender.addChatMessage(new ChatComponentText("\"toggle debugSmallOres\" - toggles worldgen small vein debug")); + sender.addChatMessage(new ChatComponentText("\"toggle debugStones\" - toggles worldgen stones debug")); + sender.addChatMessage(new ChatComponentText("\"toggle debugChunkloaders\" - toggles chunkloaders debug")); + sender.addChatMessage(new ChatComponentText("\"toggle debugMulti\" - toggles structurelib debug")); + sender.addChatMessage(new ChatComponentText("\"chunks\" - print a list of the force loaded chunks")); + sender.addChatMessage( + new ChatComponentText( + "\"pollution <amount>\" - adds the <amount> of the pollution to the current chunk, " + + "\n if <amount> isnt specified, will add" + + GT_Mod.gregtechproxy.mPollutionSmogLimit + + "gibbl.")); + sender.addChatMessage(new ChatComponentText(EnumChatFormatting.GOLD + " --- Global wireless EU controls ---")); + sender.addChatMessage(new ChatComponentText("Allows you to set the amount of EU in a users wireless network.")); + sender.addChatMessage( + new ChatComponentText( + "Usage:" + EnumChatFormatting.RED + + " global_energy_set " + + EnumChatFormatting.BLUE + + "[Name] " + + EnumChatFormatting.LIGHT_PURPLE + + "[EU]")); + sender.addChatMessage( + new ChatComponentText("Allows you to add EU to a users wireless network. Also accepts negative numbers.")); + sender.addChatMessage( + new ChatComponentText( + "Usage:" + EnumChatFormatting.RED + + " global_energy_add " + + EnumChatFormatting.BLUE + + "[Name] " + + EnumChatFormatting.LIGHT_PURPLE + + "[EU]")); + sender.addChatMessage( + new ChatComponentText( + "Allows you to join two users together into one network. Can be undone by writing the users name twice.")); + sender.addChatMessage( + new ChatComponentText( + "Usage:" + EnumChatFormatting.RED + + " global_energy_join " + + EnumChatFormatting.BLUE + + "[User joining] [User to join]")); + sender.addChatMessage(new ChatComponentText("Shows the amount of EU in a users energy network.")); + sender.addChatMessage( + new ChatComponentText( + "Usage:" + EnumChatFormatting.RED + " global_energy_display " + EnumChatFormatting.BLUE + "[Name]")); + sender.addChatMessage( + new ChatComponentText( + "\"dump_music_durations\" - dumps soundmeta/durations.json for all registered records in the game to the log. Client-only")); + } + + @Override + public List<String> addTabCompletionOptions(ICommandSender sender, String[] ss) { + List<String> l = new ArrayList<>(); + String test = ss.length == 0 ? "" : ss[0].trim(); + if (ss.length == 0 || ss.length == 1 && (test.isEmpty() || Stream + .of( + "toggle", + "chunks", + "pollution", + "global_energy_add", + "global_energy_set", + "global_energy_join", + "global_energy_display", + "dump_music_durations") + .anyMatch(s -> s.startsWith(test)))) { + Stream + .of( + "toggle", + "chunks", + "pollution", + "global_energy_add", + "global_energy_set", + "global_energy_join", + "global_energy_display", + "dump_music_durations") + .filter(s -> test.isEmpty() || s.startsWith(test)) + .forEach(l::add); + } else if (test.equals("toggle")) { + String test1 = ss[1].trim(); + Stream + .of( + "D1", + "D2", + "debugCleanroom", + "debugDriller", + "debugBlockPump", + "debugBlockMiner", + "debugWorldGen", + "debugEntityCramming", + "debugOrevein", + "debugSmallOres", + "debugStones", + "debugChunkloaders", + "debugMulti", + "debugWorldData") + .filter(s -> test1.isEmpty() || s.startsWith(test1)) + .forEach(l::add); + } + return l; + } + + @Override + public void processCommand(ICommandSender sender, String[] strings) { + if (strings.length < 1) { + printHelp(sender); + return; + } + switch (strings[0]) { + case "toggle" -> { + if (strings.length < 2) { + printHelp(sender); + return; + } + if ("debugMulti".equals(strings[1])) { + StructureLib.DEBUG_MODE = !StructureLib.DEBUG_MODE; + sender.addChatMessage( + new ChatComponentText(strings[1] + " = " + (StructureLib.DEBUG_MODE ? "true" : "false"))); + return; + } + try { + Field field = GT_Values.class.getDeclaredField(strings[1]); + if (field.getType() != boolean.class) { + sender.addChatMessage(new ChatComponentText("Wrong variable: " + strings[1])); + return; + } + boolean b = !field.getBoolean(null); + field.setBoolean(null, b); + sender.addChatMessage(new ChatComponentText(strings[1] + " = " + (b ? "true" : "false"))); + } catch (Exception e) { + sender.addChatMessage(new ChatComponentText("No such variable: " + strings[0])); + } + } + case "chunks" -> { + GT_ChunkManager.printTickets(); + sender.addChatMessage(new ChatComponentText("Forced chunks logged to GregTech.log")); + } + case "pollution" -> { + ChunkCoordinates coordinates = sender.getPlayerCoordinates(); + int amount = (strings.length < 2) ? GT_Mod.gregtechproxy.mPollutionSmogLimit + : Integer.parseInt(strings[1]); + GT_Pollution.addPollution( + sender.getEntityWorld() + .getChunkFromBlockCoords(coordinates.posX, coordinates.posZ), + amount); + } + case "global_energy_add" -> { + String username = strings[1]; + String formatted_username = EnumChatFormatting.BLUE + username + EnumChatFormatting.RESET; + UUID uuid = SpaceProjectManager.getPlayerUUIDFromName(username); + + String EU_String = strings[2]; + + // Usage is /gt global_energy_add username EU + + String EU_string_formatted = EnumChatFormatting.RED + + GT_Utility.formatNumbers(new BigInteger(EU_String)) + + EnumChatFormatting.RESET; + + if (addEUToGlobalEnergyMap(uuid, new BigInteger(EU_String))) sender.addChatMessage( + new ChatComponentText( + "Successfully added " + EU_string_formatted + + "EU to the global energy network of " + + formatted_username + + ".")); + else sender.addChatMessage( + new ChatComponentText( + "Failed to add " + EU_string_formatted + + "EU to the global energy map of " + + formatted_username + + ". Insufficient energy in network. ")); + + sender.addChatMessage( + new ChatComponentText( + formatted_username + " currently has " + + EnumChatFormatting.RED + + GT_Utility.formatNumbers(new BigInteger(getUserEU(uuid).toString())) + + EnumChatFormatting.RESET + + "EU in their network.")); + + } + case "global_energy_set" -> { + + // Usage is /gt global_energy_set username EU + + String username = strings[1]; + String formatted_username = EnumChatFormatting.BLUE + username + EnumChatFormatting.RESET; + UUID uuid = SpaceProjectManager.getPlayerUUIDFromName(username); + + String EU_String_0 = strings[2]; + + if ((new BigInteger(EU_String_0).compareTo(BigInteger.ZERO)) < 0) { + sender.addChatMessage( + new ChatComponentText("Cannot set a users energy network to a negative value.")); + break; + } + + setUserEU(uuid, new BigInteger(EU_String_0)); + + sender.addChatMessage( + new ChatComponentText( + "Successfully set " + formatted_username + + "'s global energy network to " + + EnumChatFormatting.RED + + GT_Utility.formatNumbers(new BigInteger(EU_String_0)) + + EnumChatFormatting.RESET + + "EU.")); + + } + case "global_energy_join" -> { + + // Usage is /gt global_energy_join username_of_you username_to_join + + String usernameSubject = strings[1]; + String usernameTeam = strings[2]; + + String formattedUsernameSubject = EnumChatFormatting.BLUE + usernameSubject + EnumChatFormatting.RESET; + String formattedUsernameTeam = EnumChatFormatting.BLUE + usernameTeam + EnumChatFormatting.RESET; + + UUID uuidSubject = SpaceProjectManager.getPlayerUUIDFromName(usernameSubject); + UUID uuidTeam = SpaceProjectManager.getLeader(SpaceProjectManager.getPlayerUUIDFromName(usernameTeam)); + + if (uuidSubject.equals(uuidTeam)) { + // leave team + SpaceProjectManager.putInTeam(uuidSubject, uuidSubject); + sender.addChatMessage( + new ChatComponentText( + "User " + formattedUsernameSubject + " has rejoined their own global energy network.")); + break; + } + + // join other's team + + if (uuidSubject.equals(uuidTeam)) { + sender.addChatMessage(new ChatComponentText("They are already in the same network!")); + break; + } + + SpaceProjectManager.putInTeam(uuidSubject, uuidTeam); + + sender.addChatMessage( + new ChatComponentText( + "Success! " + formattedUsernameSubject + " has joined " + formattedUsernameTeam + ".")); + sender.addChatMessage( + new ChatComponentText( + "To undo this simply join your own network again with /gt global_energy_join " + + formattedUsernameSubject + + " " + + formattedUsernameSubject + + ".")); + + } + case "global_energy_display" -> { + + // Usage is /gt global_energy_display username. + + String username = strings[1]; + String formatted_username = EnumChatFormatting.BLUE + username + EnumChatFormatting.RESET; + UUID userUUID = SpaceProjectManager.getPlayerUUIDFromName(username); + + if (!SpaceProjectManager.isInTeam(userUUID)) { + sender.addChatMessage( + new ChatComponentText("User " + formatted_username + " has no global energy network.")); + break; + } + UUID teamUUID = SpaceProjectManager.getLeader(userUUID); + + sender.addChatMessage( + new ChatComponentText( + "User " + formatted_username + + " has " + + EnumChatFormatting.RED + + GT_Utility.formatNumbers(getUserEU(userUUID)) + + EnumChatFormatting.RESET + + "EU in their network.")); + if (!userUUID.equals(teamUUID)) sender.addChatMessage( + new ChatComponentText( + "User " + formatted_username + + " is currently in network of " + + EnumChatFormatting.BLUE + + SpaceProjectManager.getPlayerNameFromUUID(teamUUID) + + EnumChatFormatting.RESET + + ".")); + + } + case "dump_music_durations" -> { + if (!FMLLaunchHandler.side() + .isClient()) { + sender + .addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "This command is client-only.")); + } + GT_MusicSystem.ClientSystem.dumpAllRecordDurations(); + } + default -> { + sender + .addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Invalid command/syntax detected.")); + printHelp(sender); + } + } + } +} 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..9cf7fd7cf8 --- /dev/null +++ b/src/main/java/gregtech/common/misc/GT_DrillingLogicDelegate.java @@ -0,0 +1,266 @@ +package gregtech.common.misc; + +import static gregtech.api.enums.GT_Values.debugBlockMiner; + +import java.util.List; + +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 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; + +/** @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 '(min |
