aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/ProcessorFactory.java2
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorBoxSolver.java221
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/boxpuzzle/BoxPuzzleSolvingThread.java135
-rw-r--r--src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/boxpuzzle/RoomProcessorBoxSolver.java291
4 files changed, 427 insertions, 222 deletions
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/ProcessorFactory.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/ProcessorFactory.java
index 33196531..44bc9fb6 100644
--- a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/ProcessorFactory.java
+++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/ProcessorFactory.java
@@ -1,6 +1,6 @@
package kr.syeyoung.dungeonsguide.roomprocessor;
-import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoom;
+import kr.syeyoung.dungeonsguide.roomprocessor.boxpuzzle.RoomProcessorBoxSolver;
import kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle.RoomProcessorWaterPuzzle;
import java.util.HashMap;
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorBoxSolver.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorBoxSolver.java
deleted file mode 100644
index 5d2d479d..00000000
--- a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorBoxSolver.java
+++ /dev/null
@@ -1,221 +0,0 @@
-package kr.syeyoung.dungeonsguide.roomprocessor;
-
-import kr.syeyoung.dungeonsguide.dungeon.data.OffsetPointSet;
-import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoom;
-import kr.syeyoung.dungeonsguide.utils.RenderUtils;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import net.minecraft.block.Block;
-import net.minecraft.client.Minecraft;
-import net.minecraft.init.Blocks;
-import net.minecraft.util.BlockPos;
-import net.minecraft.world.World;
-
-import java.awt.*;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-
-public class RoomProcessorBoxSolver extends GeneralRoomProcessor {
-
-
- private BlockPos[][] poses = new BlockPos[6][7];
- private boolean bugged= true;
- public RoomProcessorBoxSolver(DungeonRoom dungeonRoom) {
- super(dungeonRoom);
-
- OffsetPointSet ops = (OffsetPointSet) dungeonRoom.getDungeonRoomInfo().getProperties().get("board");
- try {
- if (ops != null) {
- for (int y = 0; y < 6; y++) {
- for (int x = 0; x < 7; x++) {
- poses[y][x] = ops.getOffsetPointList().get(y * 7 + x).getBlockPos(dungeonRoom);
- }
- }
- bugged = false;
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- private byte[][] buildCurrentState() {
- World w = getDungeonRoom().getContext().getWorld();
- byte[][] board = new byte[poses.length][poses[0].length];
- for (int y = 0; y < poses.length; y++) {
- for (int x = 0; x < poses[0].length; x++) {
- BlockPos pos = poses[y][x];
- Block b = w.getChunkFromBlockCoords(pos).getBlock(pos);
- if (b == Blocks.air)
- board[y][x] = 0;
- else
- board[y][x] = 1;
- }
- }
- return board;
- }
-
- private byte[][] lastboard;
-
- private static final List<Point> directions = Arrays.asList(new Point(0,-1), new Point(-1,0), new Point(1,0), new Point(0,1));
- private LinkedList<Action> solve(byte[][] board, int playerX, int playerY) { // result:: playerY == 0
- if (playerY == 0) {
- LinkedList<Action> moves = new LinkedList<Action>();
- return moves;
- }
- for (Point dir:directions) {
- int resX = playerX + dir.x;
- int resY = playerY + dir.y;
- if (resX < 0 || resY < 0 || resX >= board[0].length|| resY>=board.length || (board[resY][resX] > 1 && resY > 0) ||(board[resY][resX] > 3)) continue;
- byte[][] copied = new byte[board.length][];
- for (int y = 0; y < copied.length; y++)
- copied[y] = board[y].clone();
-
- LinkedList<Action> solved = null;
- boolean pushed = false;
- if (board[resY][resX] == 1) {
- if (!push(copied, resX, resY, dir.x, dir.y)) {
- continue;
- }
- pushed = true;
- solved = solve(copied, playerX, playerY);
- } else {
- copied[playerY][playerX] += 2;
- solved = solve(copied, resX, resY);
- }
- if (solved != null) {
- if (pushed) {
- solved.addFirst(new Push(dir.x, dir.y));
- } else {
- solved.addFirst(new Move(resX, resY));
- }
- return solved;
- }
- }
- return null;
- }
-
- public static interface Action { }
- @Data
- @AllArgsConstructor
- public static class Move implements Action {
- private int x;
- private int y;
- }
- @Data
- @AllArgsConstructor
- public static class Push implements Action {
- private int dx;
- private int dy;
- }
-
- private boolean push(byte[][] board, int x,int y,int dx,int dy) {
- if (board[y][x] != 1) return false;
- int resultingX= x + dx;
- int resultingY = y +dy;
- if (resultingX < 0 || resultingY < 0 || resultingX >= board[0].length || resultingY >= board.length) return false;
- if (board[resultingY][resultingX] == 1) return false;
-
- board[resultingY][resultingX] = 1;
- board[y][x] = 0;
- return true;
- }
-
- @Override
- public void tick() {
- super.tick();
- if (bugged) return;
- byte[][] currboard = buildCurrentState();
- boolean calculate = lastboard == null;
- if (!calculate) {
- label:
- for (int y = 0; y < 6; y ++) {
- for (int x = 0; x < 7; x++)
- if (currboard[y][x] != lastboard[y][x]) {
- calculate = true;
- break label;
- }
- }
- }
- if (calculate) {
- for (int i = 0; i < 7; i++) {
- if (currboard[5][i] == 0) {
- try {
- solution = solve(currboard, i, 5);
- if (solution != null) {
- solution.addFirst(new Move(i, 5));
- break;
- }
- } catch (Error e) {
- e.printStackTrace();
- }
- }
- }
- }
- lastboard = currboard;
- }
-
- private LinkedList<Action> solution;
-
- public Point getPlayerPos(byte[][] map) {
- BlockPos playerPos = Minecraft.getMinecraft().thePlayer.getPosition();
- int minDir = Integer.MAX_VALUE;
- Point pt = null;
- for (int y = 0; y < poses.length; y++) {
- for (int x = 0; x < poses[0].length; x++) {
- if (map[y][x] == 1) continue;
- int dir = (int) poses[y][x].distanceSq(playerPos);
- if (dir < minDir) {
- minDir = dir;
- pt = new Point(x,y);
- }
- }
- }
- return pt;
- }
-
- @Override
- public void drawWorld(float partialTicks) {
- super.drawWorld(partialTicks);
- if (bugged) return;
- if (solution == null) return;
- try {
- List<BlockPos> line = new ArrayList<BlockPos>();
- List<BlockPos> push = new ArrayList<BlockPos>();
- BlockPos lastLoc2 = null;
- Move lastLoc = null;
- for (Action action : solution) {
- if (action instanceof Move) {
- BlockPos pos = poses[((Move) action).getY()][((Move) action).getX()];
- line.add(pos.add(0, -1, 0));
- lastLoc = (Move) action;
- lastLoc2 = pos;
- } else if (action instanceof Push) {
- int y = lastLoc.getY() + ((Push) action).getDy();
- int x = lastLoc.getX() + ((Push) action).getDx();
-
- BlockPos vec = poses[y][x].subtract(lastLoc2);
- if (vec.getZ() > 1 || vec.getZ() < -1) vec = new BlockPos(vec.getX(),0,vec.getZ() >1 ? 1:-1);
- if (vec.getX() > 1 || vec.getX() < -1) vec = new BlockPos(vec.getX() >1 ? 1:-1,0,vec.getZ());
- push.add(lastLoc2.add(vec));
- }
- }
- boolean depth = Minecraft.getMinecraft().thePlayer.getPosition().getY() < 68;
-
- RenderUtils.drawLines(line, new Color(0, 255, 0, 255), partialTicks, depth);
- for (BlockPos b2:push)
- RenderUtils.highlightBlock(b2, new Color(0, 255, 0, 50), partialTicks, depth);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- public static class Generator implements RoomProcessorGenerator<RoomProcessorBoxSolver> {
- @Override
- public RoomProcessorBoxSolver createNew(DungeonRoom dungeonRoom) {
- RoomProcessorBoxSolver defaultRoomProcessor = new RoomProcessorBoxSolver(dungeonRoom);
- return defaultRoomProcessor;
- }
- }
-}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/boxpuzzle/BoxPuzzleSolvingThread.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/boxpuzzle/BoxPuzzleSolvingThread.java
new file mode 100644
index 00000000..010b5470
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/boxpuzzle/BoxPuzzleSolvingThread.java
@@ -0,0 +1,135 @@
+package kr.syeyoung.dungeonsguide.roomprocessor.boxpuzzle;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.awt.*;
+import java.util.*;
+import java.util.List;
+
+@Getter
+@Setter
+public class BoxPuzzleSolvingThread extends Thread {
+ private byte[][] data;
+ private int playerX;
+ private int playerY;
+ private Runnable callback;
+
+
+ public BoxPuzzleSolvingThread(byte[][] data, int playerX, int playerY, Runnable onDone) {
+ this.data = data;
+ this.playerX = playerX;
+ this.playerY = playerY;
+ this.callback = onDone;
+ }
+
+ LinkedList<BoxMove> solution = new LinkedList<BoxMove>();
+
+ private boolean solved = false;
+
+ @Override
+ public void run() {
+ solved = false;
+ solution = solve(data,playerX,playerY);
+ callback.run();
+ solved = true;
+ }
+
+ public static String stateString(byte[][] array) {
+ StringBuilder sb = new StringBuilder();
+ for (int y = 0; y < array.length; y++)
+ for(int x = 0; x < array[y].length; x++)
+ sb.append(array[y][x]);
+
+ return sb.toString();
+ }
+
+
+ private static LinkedList<BoxMove> solve(byte[][] board, int playerX, int playerY) {
+ for (int i = 10; i < 20; i++) {
+ LinkedList<BoxMove> solvedStateBoxMove = solve(new HashSet<String>(), board, playerX, playerY, 0, i);
+ if (solvedStateBoxMove != null)
+ return solvedStateBoxMove;
+ }
+ return null;
+ }
+
+ private static final java.util.List<Point> directions = Arrays.asList(new Point(-1,0), new Point(1,0), new Point(0,1), new Point(0,-1));
+ private static LinkedList<BoxMove> solve(Set<String> prevStates, byte[][] board, int playerX, int playerY, int recursionLevel, int maxRecursion) { // result:: playerY == 0
+ String stateId = stateString(board);
+ if (maxRecursion < recursionLevel) return null;
+ if (prevStates.contains(stateId)) return null;
+
+ java.util.Queue<Point> points = new LinkedList<Point>();
+ Set<Point> reached= new HashSet<Point>();
+ List<BoxMove> possibleBoxMoves = new ArrayList<BoxMove>();
+ points.add(new Point(playerX, playerY));
+
+ while (!points.isEmpty()) {
+ Point pt = points.poll();
+ if (pt.y == 0) {
+ return new LinkedList<BoxMove>();
+ }
+ if (reached.contains(pt)) continue;
+ reached.add(pt);
+ for (Point dir:directions) {
+ int resX= pt.x + dir.x;
+ int resY = pt.y + dir.y;
+ if (resX < 0 || resY < 0 || resX >= board[0].length || resY >= board.length) {
+ continue;
+ }
+ if (board[resY][resX] > 0) {
+ possibleBoxMoves.add(new BoxMove(resX, resY, dir.x, dir.y));
+ continue;
+ }
+ points.add(new Point(resX, resY));
+ }
+ }
+
+ prevStates.add(stateId);
+ for (BoxMove possibleBoxMove : possibleBoxMoves) {
+ byte[][] copied = new byte[board.length][];
+ for (int y = 0; y < copied.length; y++)
+ copied[y] = board[y].clone();
+
+ if (push(copied, possibleBoxMove.x, possibleBoxMove.y, possibleBoxMove.dx, possibleBoxMove.dy)){
+// System.out.println("------testing "+recursionLevel+" "+possibleBoxMove.x+","+possibleBoxMove.y);
+// print(copied);
+
+ prevStates.add(stateId);
+ LinkedList<BoxMove> moves = solve(prevStates, copied, possibleBoxMove.x, possibleBoxMove.y, recursionLevel +1, maxRecursion);
+ if (moves != null) {
+ moves.addFirst(possibleBoxMove);
+ return moves;
+ }
+ }
+ }
+ prevStates.remove(stateId);
+
+ return null;
+ }
+
+
+ private static boolean push(byte[][] board, int x,int y,int dx,int dy) {
+ if (board[y][x] != 1) return false;
+ int resultingX= x + dx;
+ int resultingY = y +dy;
+ if (resultingX < 0 || resultingY < 0 || resultingX >= board[0].length || resultingY >= board.length) return false;
+ if (board[resultingY][resultingX] == 1 || resultingY == 6) return false;
+
+ board[resultingY][resultingX] = 1;
+ board[y][x] = 0;
+ return true;
+ }
+
+ @Data
+ @AllArgsConstructor
+ public static class BoxMove {
+ int x;
+ int y;
+ int dx;
+ int dy;
+ }
+}
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/boxpuzzle/RoomProcessorBoxSolver.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/boxpuzzle/RoomProcessorBoxSolver.java
new file mode 100644
index 00000000..715252d1
--- /dev/null
+++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/boxpuzzle/RoomProcessorBoxSolver.java
@@ -0,0 +1,291 @@
+package kr.syeyoung.dungeonsguide.roomprocessor.boxpuzzle;
+
+import kr.syeyoung.dungeonsguide.dungeon.data.OffsetPointSet;
+import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoom;
+import kr.syeyoung.dungeonsguide.roomprocessor.GeneralRoomProcessor;
+import kr.syeyoung.dungeonsguide.roomprocessor.RoomProcessorGenerator;
+import kr.syeyoung.dungeonsguide.utils.RenderUtils;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import net.minecraft.block.Block;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.init.Blocks;
+import net.minecraft.util.BlockPos;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.IChatComponent;
+import net.minecraft.util.MathHelper;
+import net.minecraft.world.World;
+
+import java.awt.*;
+import java.util.*;
+import java.util.List;
+
+public class RoomProcessorBoxSolver extends GeneralRoomProcessor {
+
+
+ private BlockPos[][] poses = new BlockPos[6][7];
+ private boolean bugged= true;
+
+ private BoxPuzzleSolvingThread puzzleSolvingThread;
+
+ public RoomProcessorBoxSolver(DungeonRoom dungeonRoom) {
+ super(dungeonRoom);
+
+ OffsetPointSet ops = (OffsetPointSet) dungeonRoom.getDungeonRoomInfo().getProperties().get("board");
+ try {
+ if (ops != null) {
+ for (int y = 0; y < 6; y++) {
+ for (int x = 0; x < 7; x++) {
+ poses[y][x] = ops.getOffsetPointList().get(y * 7 + x).getBlockPos(dungeonRoom);
+ }
+ }
+ bugged = false;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private byte[][] buildCurrentState() {
+ World w = getDungeonRoom().getContext().getWorld();
+ byte[][] board = new byte[poses.length][poses[0].length];
+ for (int y = 0; y < poses.length; y++) {
+ for (int x = 0; x < poses[0].length; x++) {
+ if (y == 6) {
+ board[y][x] = 0;
+ continue;
+ }
+ BlockPos pos = poses[y][x];
+ Block b = w.getChunkFromBlockCoords(pos).getBlock(pos);
+ if (b == Blocks.air)
+ board[y][x] = 0;
+ else
+ board[y][x] = 1;
+ }
+ }
+ return board;
+ }
+
+ private boolean calcReq = true;
+
+ private boolean calcDone= false;
+ private boolean calcDone2 = false;
+ private int step = 0;
+ private byte[][] lastState;
+
+ @Override
+ public void tick() {
+ super.tick();
+ if (bugged) return;
+ byte[][] currboard = buildCurrentState();
+ if (puzzleSolvingThread == null) {
+ calcDone = false;
+ puzzleSolvingThread = new BoxPuzzleSolvingThread(currboard, 0, 5, new Runnable() {
+ @Override
+ public void run() {
+ calcDone = true;
+ calcDone2 = true;
+ }
+ });
+ puzzleSolvingThread.start();
+ }
+ if (calcReq) {
+ calcDone = false;
+ puzzleSolvingThread = new BoxPuzzleSolvingThread(currboard, 0, 5, new Runnable() {
+ @Override
+ public void run() {
+ calcDone = true;
+ calcDone2 = true;
+ }
+ });
+ puzzleSolvingThread.start();
+ calcReq = false;
+ }
+
+ boolean pathFindReq = false;
+ if (calcDone2) {
+ this.solution = puzzleSolvingThread.solution;
+ if (solution == null) {
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide :::: §cCouldn't find solution involving less than 20 box moves"));
+ } else{
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide :::: Solution Found!"));
+ }
+ step = 0;
+ lastState = currboard;
+ calcDone2 = false;
+ pathFindReq = true;
+ }
+
+ if (lastState == null) return;
+ boolean moved = false;
+ label:
+ for (int y = 0 ; y < currboard.length; y++) {
+ for (int x = 0; x < currboard[y].length; x++) {
+ if (lastState[y][x] != currboard[y][x]) {
+ moved = true;
+ break label;
+ }
+ }
+ }
+
+ if (moved) {
+ step++;
+ if (step == solution.size()) {
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide :::: Congratulations! box puzzle is now solved"));
+ }
+ }
+
+ Point player = getPlayerPos(currboard);
+ boolean currYState = Minecraft.getMinecraft().thePlayer.getPosition().getY() < 68;
+ if (((currYState && !player.equals(lastPlayer)) || (currYState != yState) || (moved) || pathFindReq) && solution != null) {
+ Point target = null;
+ if (step < solution.size()) {
+ BoxPuzzleSolvingThread.BoxMove boxMove = solution.get(step);
+ target = new Point(boxMove.x - boxMove.dx, boxMove.y - boxMove.dy);
+ }
+ List<Point> semi_pathFound = pathfind(currboard, player, target);
+ pathFound = new LinkedList<BlockPos>();
+ for (Point point : semi_pathFound) {
+ pathFound.add(poses[point.y][point.x].add(0,-1,0));
+ }
+
+ lastPlayer = player;
+ yState = currYState;
+ }
+
+ }
+ private boolean yState = true;
+ public Point getPlayerPos(byte[][] map) {
+ BlockPos playerPos = Minecraft.getMinecraft().thePlayer.getPosition();
+ int minDir = Integer.MAX_VALUE;
+ Point pt = null;
+ for (int y = 0; y < poses.length; y++) {
+ for (int x = 0; x < poses[0].length; x++) {
+ if (map[y][x] == 1) continue;
+ int dir = (int) poses[y][x].distanceSq(playerPos);
+ if (dir < minDir) {
+ minDir = dir;
+ pt = new Point(x,y);
+ }
+ }
+ }
+ return pt;
+ }
+
+ private List<BoxPuzzleSolvingThread.BoxMove> solution;
+ private List<BlockPos> pathFound;
+ private Point lastPlayer;
+
+ private static final java.util.List<Point> directions = Arrays.asList(new Point(-1,0), new Point(1,0), new Point(0,1), new Point(0,-1));
+ public List<Point> pathfind(byte[][] map, Point start, Point target2) {
+ int[][] distances = new int[map.length][map[0].length];
+
+ Queue<Point> evalulate = new LinkedList<Point>();
+ evalulate.add(start);
+ Point target = null;
+ while (!evalulate.isEmpty()) {
+ Point p = evalulate.poll();
+ if (p.equals(target2) || (target2 == null &&p.y == 0)) {
+ target = p;
+ break;
+ }
+ int max = 0;
+ for (Point dir:directions) {
+ int resX= p.x + dir.x;
+ int resY = p.y + dir.y;
+ if (resX < 0 || resY < 0 || resX >= distances[0].length || resY >= distances.length) {
+ continue;
+ }
+
+ if (max < distances[resY][resX]) {
+ max = distances[resY][resX];
+ }
+ if (distances[resY][resX] == 0 && map[resY][resX] == 0) {
+ evalulate.add(new Point(resX, resY));
+ }
+ }
+ distances[p.y][p.x] = max + 1;
+ }
+ if (target == null) return Collections.emptyList();
+
+ List<Point> route = new LinkedList<Point>();
+ while(!target.equals(start)) {
+ route.add(target);
+ int min = Integer.MAX_VALUE;
+ Point minPoint = null;
+ for (Point dir:directions) {
+ int resX= target.x + dir.x;
+ int resY = target.y + dir.y;
+ if (resX < 0 || resY < 0 || resX >= distances[0].length || resY >= distances.length) {
+ continue;
+ }
+
+ if (min > distances[resY][resX] && distances[resY][resX] != 0) {
+ min = distances[resY][resX];
+ minPoint = new Point(resX, resY);
+ }
+ }
+ target = minPoint;
+ }
+ route.add(start);
+ return route;
+ }
+
+ @Override
+ public void chatReceived(IChatComponent chat) {
+ if (chat.getFormattedText().toLowerCase().contains("recalc")) {
+ if (calcDone) {
+ calcReq = true;
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide :::: Recalculating Route..."));
+ } else {
+ calcReq = true;
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide :::: Currently Calculating Route..."));
+ }
+ }
+ }
+
+ @Override
+ public void drawScreen(float partialTicks) {
+ super.drawScreen(partialTicks);
+ FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
+ fr.drawString("Type recalc in chat for recalculation of route", 10, Minecraft.getMinecraft().displayHeight / 2, 0xFFFFFF);
+ }
+
+ @Override
+ public void drawWorld(float partialTicks) {
+ super.drawWorld(partialTicks);
+ if (bugged) return;
+ if (!calcDone) return;
+ if (solution == null) return;
+ if (step < solution.size()) {
+ BoxPuzzleSolvingThread.BoxMove boxMove = solution.get(step);
+ int fromX = boxMove.x - boxMove.dx;
+ int fromY = boxMove.y - boxMove.dy;
+
+ BlockPos pos = poses[fromY][fromX];
+ BlockPos pos2 = poses[boxMove.y][boxMove.x];
+ BlockPos dir = pos.subtract(pos2);
+ dir = new BlockPos(MathHelper.clamp_int(dir.getX(), -1,1), 0, MathHelper.clamp_double(dir.getZ(), -1, 1));
+
+ BlockPos highlight = pos2.add(dir);
+ RenderUtils.highlightBlock(highlight, new Color(0,255,0,MathHelper.clamp_int((int) (255 - Minecraft.getMinecraft().thePlayer.getPosition().distanceSq(highlight)),50,255)), partialTicks, false);
+ }
+
+ if (pathFound != null) {
+ RenderUtils.drawLines(pathFound, new Color(0,255,0,255), partialTicks, true);
+ }
+
+ }
+
+ public static class Generator implements RoomProcessorGenerator<RoomProcessorBoxSolver> {
+ @Override
+ public RoomProcessorBoxSolver createNew(DungeonRoom dungeonRoom) {
+ RoomProcessorBoxSolver defaultRoomProcessor = new RoomProcessorBoxSolver(dungeonRoom);
+ return defaultRoomProcessor;
+ }
+ }
+
+
+
+}