aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/common/misc
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/gregtech/common/misc')
-rw-r--r--src/main/java/gregtech/common/misc/GT_ClientPollutionMap.java140
-rw-r--r--src/main/java/gregtech/common/misc/GT_Command.java340
-rw-r--r--src/main/java/gregtech/common/misc/GT_DrillingLogicDelegate.java266
-rw-r--r--src/main/java/gregtech/common/misc/GT_IDrillingLogicDelegateOwner.java22
-rw-r--r--src/main/java/gregtech/common/misc/GlobalEnergyWorldSavedData.java125
-rw-r--r--src/main/java/gregtech/common/misc/GlobalMetricsCoverDatabase.java492
-rw-r--r--src/main/java/gregtech/common/misc/GlobalVariableStorage.java15
-rw-r--r--src/main/java/gregtech/common/misc/WirelessNetworkManager.java93
-rw-r--r--src/main/java/gregtech/common/misc/spaceprojects/SpaceProjectManager.java309
-rw-r--r--src/main/java/gregtech/common/misc/spaceprojects/SpaceProjectWorldSavedData.java343
-rw-r--r--src/main/java/gregtech/common/misc/spaceprojects/base/SP_Requirements.java74
-rw-r--r--src/main/java/gregtech/common/misc/spaceprojects/base/SP_Upgrade.java362
-rw-r--r--src/main/java/gregtech/common/misc/spaceprojects/base/SpaceProject.java451
-rw-r--r--src/main/java/gregtech/common/misc/spaceprojects/commands/SPM_Command.java288
-rw-r--r--src/main/java/gregtech/common/misc/spaceprojects/commands/SP_Command.java166
-rw-r--r--src/main/java/gregtech/common/misc/spaceprojects/enums/JsonVariables.java22
-rw-r--r--src/main/java/gregtech/common/misc/spaceprojects/enums/SolarSystem.java104
-rw-r--r--src/main/java/gregtech/common/misc/spaceprojects/enums/SpaceBodyType.java17
-rw-r--r--src/main/java/gregtech/common/misc/spaceprojects/enums/StarType.java32
-rw-r--r--src/main/java/gregtech/common/misc/spaceprojects/enums/UpgradeStatus.java11
-rw-r--r--src/main/java/gregtech/common/misc/spaceprojects/interfaces/ISpaceBody.java37
-rw-r--r--src/main/java/gregtech/common/misc/spaceprojects/interfaces/ISpaceProject.java430
22 files changed, 4139 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..3bf73b6300
--- /dev/null
+++ b/src/main/java/gregtech/common/misc/GT_Command.java
@@ -0,0 +1,340 @@
+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 gregtech.GT_Mod;
+import gregtech.api.enums.GT_Values;
+import gregtech.api.objects.GT_ChunkManager;
+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.";
+ }
+
+ private void printHelp(ICommandSender sender) {
+ sender.addChatMessage(
+ new ChatComponentText(
+ "Usage: gt <toggle|chunks|pollution|global_energy_add|global_energy_set|global_energy_join>"));
+ 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]"));
+ }
+
+ @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")
+ .anyMatch(s -> s.startsWith(test)))) {
+ Stream
+ .of(
+ "toggle",
+ "chunks",
+ "pollution",
+ "global_energy_add",
+ "global_energy_set",
+ "global_energy_join",
+ "global_energy_display")
+ .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
+ + "."));
+
+ }
+ 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 '(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.setPos