aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/me/Danker/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/me/Danker/utils')
-rw-r--r--src/main/java/me/Danker/utils/BoulderUtils.java280
-rw-r--r--src/main/java/me/Danker/utils/Utils.java78
2 files changed, 315 insertions, 43 deletions
diff --git a/src/main/java/me/Danker/utils/BoulderUtils.java b/src/main/java/me/Danker/utils/BoulderUtils.java
new file mode 100644
index 0000000..2d437d0
--- /dev/null
+++ b/src/main/java/me/Danker/utils/BoulderUtils.java
@@ -0,0 +1,280 @@
+package me.Danker.utils;
+
+import me.Danker.features.puzzlesolvers.BoulderSolver;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.util.BlockPos;
+import net.minecraft.util.Vec3;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+
+public class BoulderUtils {
+
+ public static HashSet<String> seenBoardStates = new HashSet<>();
+ public static long iterations = 0;
+ public static int fastestSolution = 10;
+
+ /*
+ CC BY-SA 4.0
+ Unmodified
+ Question: https://stackoverflow.com/questions/5617016/
+ Answer: https://stackoverflow.com/a/53397359
+ Author: https://stackoverflow.com/users/3647002/gayan-weerakutti
+ */
+ public static char[][] copy(char[][] array) {
+ return Arrays.stream(array).map(char[]::clone).toArray(char[][]::new);
+ }
+
+ public static char[][] flipVertically(char[][] board) {
+ char[][] newBoard = new char[7][7];
+
+ for (int row = 0; row < 7; row++) {
+ System.arraycopy(board[6 - row], 0, newBoard[row], 0, 7);
+ }
+
+ return newBoard;
+ }
+
+ public static char[][] flipHorizontally(char[][] board) {
+ char[][] newBoard = new char[7][7];
+
+ for (int row = 0; row < 7; row++) {
+ for (int column = 0; column < 7; column++) {
+ newBoard[row][column] = board[row][6 - column];
+ }
+ }
+
+ return newBoard;
+ }
+
+ public static char[][] rotateClockwise(char[][] board) {
+ char[][] newBoard = new char[7][7];
+
+ for (int row = 0; row < 7; row++) {
+ for (int column = 0; column < 7; column++) {
+ newBoard[column][6 - row] = board[row][column];
+ }
+ }
+
+ return newBoard;
+ }
+
+ public static char[][] removeFirstRow(char[][] board) {
+ List<char[]> list = new ArrayList<>(Arrays.asList(board));
+ list.remove(0);
+ return list.toArray(new char[][]{});
+ }
+
+ public static String toString(char[][] board) {
+ StringBuilder sb = new StringBuilder();
+ for (char[] row : board) {
+ for (char column : row) {
+ sb.append(column);
+ }
+ }
+ return sb.toString();
+ }
+
+ public static int findSolution(char[][] board, int depth, List<int[]> route) {
+ if (depth > 9) return 10;
+ String boardString = toString(board);
+ if (seenBoardStates.contains(boardString)) return 10; // this line turns 600 million iterations to 700 thousand
+ seenBoardStates.add(boardString);
+ if (hasOpenPath(board)) return depth;
+
+ char[][] floodFilledBoard = floodFillBottom(board);
+ List<int[]> newRoute = new ArrayList<>(route);
+ int solutionLength = 10;
+ int bestRow = -1;
+ int bestColumn = -1;
+ int bestDirection = -1;
+ for (int row = 0; row < 6; row++) {
+ for (int column = 0; column < 7; column++) {
+ iterations++;
+ if (floodFilledBoard[row][column] == 'X' && isTouchingOpenSpace(floodFilledBoard, row, column)) {
+ if (canBePushed(floodFilledBoard, row, column, 'u')) {
+ int solution = findSolution(push(board, row, column, 'u'), depth + 1, add(newRoute, new int[]{row, column, 1}));
+ if (solution < solutionLength) {
+ solutionLength = solution;
+ bestRow = row;
+ bestColumn = column;
+ bestDirection = 1;
+ }
+ }
+ if (canBePushed(floodFilledBoard, row, column, 'd')) {
+ int solution = findSolution(push(board, row, column, 'd'), depth + 1, add(newRoute, new int[]{row, column, 2}));
+ if (solution < solutionLength) {
+ solutionLength = solution;
+ bestRow = row;
+ bestColumn = column;
+ bestDirection = 2;
+ }
+ }
+ if (canBePushed(floodFilledBoard, row, column, 'l')) {
+ int solution = findSolution(push(board, row, column, 'l'), depth + 1, add(newRoute, new int[]{row, column, 3}));
+ if (solution < solutionLength) {
+ solutionLength = solution;
+ bestRow = row;
+ bestColumn = column;
+ bestDirection = 3;
+ }
+ }
+ if (canBePushed(floodFilledBoard, row, column, 'r')) {
+ int solution = findSolution(push(board, row, column, 'r'), depth + 1, add(newRoute, new int[]{row, column, 4}));
+ if (solution < solutionLength) {
+ solutionLength = solution;
+ bestRow = row;
+ bestColumn = column;
+ bestDirection = 4;
+ }
+ }
+ }
+ }
+ }
+
+ if (bestRow != -1) {
+ newRoute.add(0, new int[]{bestRow, bestColumn, bestDirection});
+ }
+ if (solutionLength < fastestSolution) {
+ fastestSolution = solutionLength;
+ newRoute.add(newRoute.remove(0)); // dont know why the last one goes first but this fixes it
+ BoulderSolver.route = new ArrayList<>(newRoute);
+ }
+ return solutionLength;
+ }
+
+ public static boolean canBePushed(char[][] floodFilledBoard, int row, int column, char direction) {
+ switch (direction) {
+ case 'u':
+ if (row > 0 && row < 5 && floodFilledBoard[row - 1][column] != 'X' && floodFilledBoard[row + 1][column] == 'O') return true;
+ break;
+ case 'd':
+ if (row > 0 && row < 5 && floodFilledBoard[row - 1][column] == 'O' && floodFilledBoard[row + 1][column] != 'X') return true;
+ break;
+ case 'l':
+ if (column > 0 && column < 6 && floodFilledBoard[row][column - 1] != 'X' && floodFilledBoard[row][column + 1] == 'O') return true;
+ break;
+ case 'r':
+ if (column > 0 && column < 6 && floodFilledBoard[row][column - 1] == 'O' && floodFilledBoard[row][column + 1] != 'X') return true;
+ break;
+ }
+ return false;
+ }
+
+ public static char[][] push(char[][] board, int row, int column, char direction) {
+ char[][] newBoard = copy(board);
+ switch (direction) {
+ case 'u':
+ newBoard[row - 1][column] = 'X';
+ break;
+ case 'd':
+ newBoard[row + 1][column] = 'X';
+ break;
+ case 'l':
+ newBoard[row][column - 1] = 'X';
+ break;
+ case 'r':
+ newBoard[row][column + 1] = 'X';
+ }
+ newBoard[row][column] = '\0';
+ return newBoard;
+ }
+
+ public static boolean isTouchingOpenSpace(char[][] floodFilledBoard, int row, int column) {
+ return (row > 0 && floodFilledBoard[row - 1][column] == 'O') ||
+ (row < 5 && floodFilledBoard[row + 1][column] == 'O') ||
+ (column > 0 && floodFilledBoard[row][column - 1] == 'O') ||
+ (column < 6 && floodFilledBoard[row][column + 1] == 'O');
+ }
+
+ public static boolean hasOpenPath(char[][] board) {
+ char[][] newBoard = floodFillBottom(copy(board));
+ // Check if flood fill reached top
+ for (int column = 0; column < 7; column++) {
+ if (newBoard[0][column] == 'O') return true;
+ }
+ return false;
+ }
+
+ public static char[][] floodFillBottom(char[][] board) {
+ char[][] newBoard = copy(board);
+ for (int column = 0; column < 7; column++) {
+ if (newBoard[5][column] == '\0') {
+ newBoard = floodFill(newBoard, 5, column);
+ }
+ }
+ return newBoard;
+ }
+
+ public static char[][] floodFill(char[][] board, int row, int column) {
+ if (row < 0 || row > 5 || column < 0 || column > 6) return board;
+ if (board[row][column] == '\0') {
+ board[row][column] = 'O';
+ floodFill(board, row - 1, column);
+ floodFill(board, row + 1, column);
+ floodFill(board, row, column - 1);
+ floodFill(board, row, column + 1);
+ return board;
+ }
+ return board;
+ }
+
+ public static List<int[]> add(List<int[]> list, int[] arrayToAdd) {
+ List<int[]> newList = new ArrayList<>(list);
+ newList.add(arrayToAdd);
+ return newList;
+ }
+
+ public static AxisAlignedBB getBoulder(int row, int column, BlockPos chestLocation, String boulderRoomDirection) {
+ BlockPos boulderPosition;
+ switch (boulderRoomDirection) {
+ case "north":
+ boulderPosition = chestLocation.add(3 * column - 10, -2, 3 * row + 4);
+ break;
+ case "east":
+ boulderPosition = chestLocation.add(-3 * row - 6, -2, 3 * column - 10);
+ break;
+ case "south":
+ boulderPosition = chestLocation.add(-3 * column + 8, -2, -3 * row - 6);
+ break;
+ case "west":
+ boulderPosition = chestLocation.add(3 * row + 4, -2, -3 * column + 8);
+ break;
+ default:
+ return null;
+ }
+ return new AxisAlignedBB(boulderPosition.getX() - 0.01, boulderPosition.getY() - 0.01, boulderPosition.getZ() - 0.01, boulderPosition.getX() + 3.01, boulderPosition.getY() + 3.01, boulderPosition.getZ() + 3.01);
+ }
+
+ public static void drawArrow(AxisAlignedBB aabb, String boulderRoomDirection, char direction, int colourInt, float partialTicks) {
+ double averageX = (aabb.minX + aabb.maxX) / 2;
+ double thirtyPercent = (aabb.maxX - aabb.minX) * 0.3;
+ double averageZ = (aabb.minZ + aabb.maxZ) / 2;
+ if (((boulderRoomDirection.equals("north") || boulderRoomDirection.equals("south")) && (direction == 'u' || direction == 'd')) ||
+ ((boulderRoomDirection.equals("east") || boulderRoomDirection.equals("west")) && (direction == 'l' || direction == 'r'))) {
+ Utils.draw3DLine(new Vec3(averageX, aabb.minY, aabb.minZ), new Vec3(averageX, aabb.minY, aabb.maxZ), colourInt, 10, false, partialTicks);
+ } else {
+ Utils.draw3DLine(new Vec3(aabb.minX, aabb.minY, averageZ), new Vec3(aabb.maxX, aabb.minY, averageZ), colourInt, 10, false, partialTicks);
+ }
+
+ if ((boulderRoomDirection.equals("north") && direction == 'u') || (boulderRoomDirection.equals("south") && direction == 'd') ||
+ (boulderRoomDirection.equals("east") && direction == 'l') || (boulderRoomDirection.equals("west") && direction == 'r')) {
+ Utils.draw3DLine(new Vec3(averageX, aabb.minY, aabb.minZ), new Vec3(aabb.minX + thirtyPercent, aabb.minY, aabb.minZ + thirtyPercent), colourInt, 10, false, partialTicks);
+ Utils.draw3DLine(new Vec3(averageX, aabb.minY, aabb.minZ), new Vec3(aabb.maxX - thirtyPercent, aabb.minY, aabb.minZ + thirtyPercent), colourInt, 10, false, partialTicks);
+ } else if ((boulderRoomDirection.equals("north") && direction == 'd') || (boulderRoomDirection.equals("south") && direction == 'u') ||
+ (boulderRoomDirection.equals("east") && direction == 'r') || (boulderRoomDirection.equals("west") && direction == 'l')) {
+ Utils.draw3DLine(new Vec3(averageX, aabb.minY, aabb.maxZ), new Vec3(aabb.minX + thirtyPercent, aabb.minY, aabb.maxZ - thirtyPercent), colourInt, 10, false, partialTicks);
+ Utils.draw3DLine(new Vec3(averageX, aabb.minY, aabb.maxZ), new Vec3(aabb.maxX - thirtyPercent, aabb.minY, aabb.maxZ - thirtyPercent), colourInt, 10, false, partialTicks);
+ } else if ((boulderRoomDirection.equals("north") && direction == 'l') || (boulderRoomDirection.equals("south") && direction == 'r') ||
+ (boulderRoomDirection.equals("east") && direction == 'd') || (boulderRoomDirection.equals("west") && direction == 'u')) {
+ Utils.draw3DLine(new Vec3(aabb.minX, aabb.minY, averageZ), new Vec3(aabb.minX + thirtyPercent, aabb.minY, aabb.minZ + thirtyPercent), colourInt, 10, false, partialTicks);
+ Utils.draw3DLine(new Vec3(aabb.minX, aabb.minY, averageZ), new Vec3(aabb.minX + thirtyPercent, aabb.minY, aabb.maxZ - thirtyPercent), colourInt, 10, false, partialTicks);
+ } else {
+ Utils.draw3DLine(new Vec3(aabb.maxX, aabb.minY, averageZ), new Vec3(aabb.maxX - thirtyPercent, aabb.minY, aabb.minZ + thirtyPercent), colourInt, 10, false, partialTicks);
+ Utils.draw3DLine(new Vec3(aabb.maxX, aabb.minY, averageZ), new Vec3(aabb.maxX - thirtyPercent, aabb.minY, aabb.maxZ - thirtyPercent), colourInt, 10, false, partialTicks);
+ }
+ }
+
+}
diff --git a/src/main/java/me/Danker/utils/Utils.java b/src/main/java/me/Danker/utils/Utils.java
index b7c2ddf..1a24c69 100644
--- a/src/main/java/me/Danker/utils/Utils.java
+++ b/src/main/java/me/Danker/utils/Utils.java
@@ -1,6 +1,7 @@
package me.Danker.utils;
import me.Danker.DankersSkyblockMod;
+import me.Danker.features.GoldenEnchants;
import me.Danker.handlers.ScoreboardHandler;
import me.Danker.handlers.TextRenderer;
import net.minecraft.block.Block;
@@ -24,7 +25,9 @@ import net.minecraft.util.*;
import org.lwjgl.opengl.GL11;
import java.awt.*;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
@@ -62,11 +65,11 @@ public class Utils {
}
public static String returnGoldenEnchants(String line) {
- Matcher matcher = DankersSkyblockMod.t6EnchantPattern.matcher(line);
+ Matcher matcher = GoldenEnchants.t6EnchantPattern.matcher(line);
StringBuffer out = new StringBuffer();
while (matcher.find()) {
- matcher.appendReplacement(out, DankersSkyblockMod.t6Enchants.get(matcher.group(1)));
+ matcher.appendReplacement(out, GoldenEnchants.t6Enchants.get(matcher.group(1)));
}
matcher.appendTail(out);
@@ -118,7 +121,7 @@ public class Utils {
}
}
- public static boolean isOnHypixel () {
+ public static boolean isOnHypixel() {
Minecraft mc = Minecraft.getMinecraft();
if (mc != null && mc.theWorld != null && !mc.isSingleplayer()) {
return mc.getCurrentServerData().serverIP.toLowerCase().contains("hypixel");
@@ -270,7 +273,7 @@ public class Utils {
return bool ? EnumChatFormatting.GREEN + "On" : EnumChatFormatting.RED + "Off";
}
- //Taken from SkyblockAddons
+ // Taken from SkyblockAddons
public static List<String> getItemLore(ItemStack itemStack) {
final int NBT_INTEGER = 3;
final int NBT_STRING = 8;
@@ -296,14 +299,13 @@ public class Utils {
}
public static boolean hasRightClickAbility(ItemStack itemStack) {
- return Utils.getItemLore(itemStack).stream().anyMatch(line->{
+ return Utils.getItemLore(itemStack).stream().anyMatch(line -> {
String stripped = StringUtils.stripControlCodes(line);
return stripped.startsWith("Item Ability:") && stripped.endsWith("RIGHT CLICK");
});
}
-
-
- public static void draw3DLine(Vec3 pos1, Vec3 pos2, int colourInt, float partialTicks) {
+
+ public static void draw3DLine(Vec3 pos1, Vec3 pos2, int colourInt, int lineWidth, boolean depth, float partialTicks) {
Entity render = Minecraft.getMinecraft().getRenderViewEntity();
WorldRenderer worldRenderer = Tessellator.getInstance().getWorldRenderer();
Color colour = new Color(colourInt);
@@ -318,7 +320,11 @@ public class Utils {
GlStateManager.enableBlend();
GlStateManager.disableAlpha();
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
- GL11.glLineWidth(2);
+ GL11.glLineWidth(lineWidth);
+ if (!depth) {
+ GL11.glDisable(GL11.GL_DEPTH_TEST);
+ GlStateManager.depthMask(false);
+ }
GlStateManager.color(colour.getRed() / 255f, colour.getGreen() / 255f, colour.getBlue() / 255f, colour.getAlpha() / 255f);
worldRenderer.begin(GL11.GL_LINE_STRIP, DefaultVertexFormats.POSITION);
@@ -327,6 +333,10 @@ public class Utils {
Tessellator.getInstance().draw();
GlStateManager.translate(realX, realY, realZ);
+ if (!depth) {
+ GL11.glEnable(GL11.GL_DEPTH_TEST);
+ GlStateManager.depthMask(true);
+ }
GlStateManager.disableBlend();
GlStateManager.enableAlpha();
GlStateManager.enableTexture2D();
@@ -357,11 +367,9 @@ public class Utils {
GlStateManager.disableBlend();
GlStateManager.popMatrix();
}
-
- // Yoinked from ForgeHax
+
public static void draw3DBox(AxisAlignedBB aabb, int colourInt, float partialTicks) {
- Entity render = Minecraft.getMinecraft().getRenderViewEntity();
- WorldRenderer worldRenderer = Tessellator.getInstance().getWorldRenderer();
+ Entity render = Minecraft.getMinecraft().getRenderViewEntity();
Color colour = new Color(colourInt);
double realX = render.lastTickPosX + (render.posX - render.lastTickPosX) * partialTicks;
@@ -375,33 +383,9 @@ public class Utils {
GlStateManager.disableAlpha();
GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
GL11.glLineWidth(2);
- GlStateManager.color(colour.getRed() / 255f, colour.getGreen() / 255f, colour.getBlue() / 255f, colour.getAlpha() / 255f);
- worldRenderer.begin(GL11.GL_LINE_STRIP, DefaultVertexFormats.POSITION);
-
- worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex();
- worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex();
- worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex();
- worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex();
- worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex();
- Tessellator.getInstance().draw();
- worldRenderer.begin(GL11.GL_LINE_STRIP, DefaultVertexFormats.POSITION);
- worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex();
- worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex();
- worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex();
- worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex();
- worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex();
- Tessellator.getInstance().draw();
- worldRenderer.begin(GL11.GL_LINE_STRIP, DefaultVertexFormats.POSITION);
- worldRenderer.pos(aabb.minX, aabb.minY, aabb.minZ).endVertex();
- worldRenderer.pos(aabb.minX, aabb.maxY, aabb.minZ).endVertex();
- worldRenderer.pos(aabb.maxX, aabb.minY, aabb.minZ).endVertex();
- worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.minZ).endVertex();
- worldRenderer.pos(aabb.maxX, aabb.minY, aabb.maxZ).endVertex();
- worldRenderer.pos(aabb.maxX, aabb.maxY, aabb.maxZ).endVertex();
- worldRenderer.pos(aabb.minX, aabb.minY, aabb.maxZ).endVertex();
- worldRenderer.pos(aabb.minX, aabb.maxY, aabb.maxZ).endVertex();
- Tessellator.getInstance().draw();
-
+
+ RenderGlobal.drawOutlinedBoundingBox(aabb, colour.getRed(), colour.getGreen(), colour.getBlue(), colour.getAlpha());
+
GlStateManager.translate(realX, realY, realZ);
GlStateManager.disableBlend();
GlStateManager.enableAlpha();
@@ -410,7 +394,7 @@ public class Utils {
GlStateManager.popMatrix();
}
- public static void drawFilled3DBox(AxisAlignedBB aabb, int colourInt, boolean translucent, float partialTicks) {
+ public static void drawFilled3DBox(AxisAlignedBB aabb, int colourInt, boolean translucent, boolean depth, float partialTicks) {
Entity render = Minecraft.getMinecraft().getRenderViewEntity();
WorldRenderer worldRenderer = Tessellator.getInstance().getWorldRenderer();
Color colour = new Color(colourInt);
@@ -425,8 +409,12 @@ public class Utils {
GlStateManager.disableTexture2D();
GlStateManager.enableAlpha();
GlStateManager.enableBlend();
- GlStateManager.tryBlendFuncSeparate(770, translucent ? 1 : 771, 1, 0);
GlStateManager.disableCull();
+ GlStateManager.tryBlendFuncSeparate(770, translucent ? 1 : 771, 1, 0);
+ if (!depth) {
+ GL11.glDisable(GL11.GL_DEPTH_TEST);
+ GlStateManager.depthMask(false);
+ }
GlStateManager.color(colour.getRed() / 255f, colour.getGreen() / 255f, colour.getBlue() / 255f, colour.getAlpha() / 255f);
worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION);
// Bottom
@@ -462,6 +450,10 @@ public class Utils {
Tessellator.getInstance().draw();
GlStateManager.translate(realX, realY, realZ);
+ if (!depth) {
+ GL11.glEnable(GL11.GL_DEPTH_TEST);
+ GlStateManager.depthMask(true);
+ }
GlStateManager.enableCull();
GlStateManager.disableAlpha();
GlStateManager.disableBlend();