aboutsummaryrefslogtreecommitdiff
path: root/mod
diff options
context:
space:
mode:
Diffstat (limited to 'mod')
-rwxr-xr-xmod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/LeverState.java33
-rwxr-xr-xmod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/LeverStateContradict.java25
-rwxr-xr-xmod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/RoomProcessorWaterPuzzle.java215
-rwxr-xr-xmod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/Route.java60
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/Simulator.java257
-rwxr-xr-xmod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/SwitchData.java46
-rwxr-xr-xmod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/WaterBoard.java423
-rwxr-xr-xmod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/WaterNode.java36
-rw-r--r--mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/WaterPathfinder.java204
-rwxr-xr-xmod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeAir.java59
-rwxr-xr-xmod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeEnd.java60
-rwxr-xr-xmod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeStart.java66
-rwxr-xr-xmod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeToggleable.java71
-rwxr-xr-xmod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeWall.java62
14 files changed, 645 insertions, 972 deletions
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/LeverState.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/LeverState.java
deleted file mode 100755
index e86fdd5c..00000000
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/LeverState.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-
-@Data
-@AllArgsConstructor
-public class LeverState {
- private String blockId;
- private boolean requiredState;
-
- public LeverState invert() {
- return new LeverState(blockId, !requiredState);
- }
-}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/LeverStateContradict.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/LeverStateContradict.java
deleted file mode 100755
index a574d6bf..00000000
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/LeverStateContradict.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle;
-
-public class LeverStateContradict extends LeverState {
- public LeverStateContradict() {
- super("contradict", true);
- }
-}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/RoomProcessorWaterPuzzle.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/RoomProcessorWaterPuzzle.java
index 98ac9cc9..fccfcaa1 100755
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/RoomProcessorWaterPuzzle.java
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/RoomProcessorWaterPuzzle.java
@@ -25,21 +25,43 @@ import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.GeneralRoomProcessor;
import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.RoomProcessorGenerator;
import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry;
import kr.syeyoung.dungeonsguide.mod.utils.RenderUtils;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockLever;
+import net.minecraft.block.BlockLiquid;
+import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.world.World;
import java.awt.*;
+import java.util.*;
import java.util.List;
+import java.util.stream.Collectors;
public class RoomProcessorWaterPuzzle extends GeneralRoomProcessor {
private boolean argumentsFulfilled = false;
- private WaterBoard waterBoard;
private final OffsetPointSet doorsClosed;
private final OffsetPointSet levers;
private final OffsetPointSet frontBoard;
private final OffsetPointSet backBoard;
- private final OffsetPoint water_lever;
+
+
+
+ private Simulator.Node nodes[][];
+ private Simulator.Pt waterNodeStart;
+ private Map<String, Simulator.Pt> waterNodeEnds = new HashMap<>();
+ private Map<String, List<Simulator.Pt>> switchFlips = new HashMap<>();
+ private Map<String, BlockPos> switchLoc = new HashMap<>();
+ private List<String> targetDoors = new ArrayList<>();
+
+ private Map<Simulator.Pt, BlockPos> ptMapping = new HashMap<>();
+
+ private Thread t;
+ private List<WaterPathfinder.NodeNode> solutionList = new ArrayList<>();
+ private long lastStable;
+ private long lastUnstable;
public RoomProcessorWaterPuzzle(DungeonRoom dungeonRoom) {
super(dungeonRoom);
@@ -47,28 +69,162 @@ public class RoomProcessorWaterPuzzle extends GeneralRoomProcessor {
backBoard = (OffsetPointSet) dungeonRoom.getDungeonRoomInfo().getProperties().get("back");
levers = (OffsetPointSet) dungeonRoom.getDungeonRoomInfo().getProperties().get("levers");
doorsClosed = (OffsetPointSet) dungeonRoom.getDungeonRoomInfo().getProperties().get("doors");
- water_lever = (OffsetPoint) dungeonRoom.getDungeonRoomInfo().getProperties().get("water-lever");
+ OffsetPoint water_lever = (OffsetPoint) dungeonRoom.getDungeonRoomInfo().getProperties().get("water-lever");
if (frontBoard == null || backBoard == null || levers == null || doorsClosed == null ||water_lever == null) {
argumentsFulfilled = false;
} else {
argumentsFulfilled = true;
- try {
- waterBoard = new WaterBoard(this, frontBoard, backBoard, levers, doorsClosed, water_lever);
- } catch (Exception e) {
- e.printStackTrace();
+ buildLeverStates();
+ buildNodes(true);
+ targetDoors();
+
+ }
+
+
+
+ }
+
+
+ private void buildLeverStates(){
+ for (OffsetPoint offsetPoint : levers.getOffsetPointList()) {
+ if (offsetPoint.getBlock(getDungeonRoom()) == Blocks.lever){
+ BlockPos pos = offsetPoint.getBlockPos(getDungeonRoom());
+ World w= getDungeonRoom().getContext().getWorld();
+ BlockLever.EnumOrientation enumOrientation = w.getBlockState(pos).getValue(BlockLever.FACING);
+ EnumFacing enumFacing = enumOrientation.getFacing();
+ BlockPos newPos = pos.add(-enumFacing.getDirectionVec().getX(),0,-enumFacing.getDirectionVec().getZ());
+
+ int id = Block.getIdFromBlock(w.getChunkFromBlockCoords(newPos).getBlock(newPos));
+ int data = w.getChunkFromBlockCoords(newPos).getBlockMetadata(newPos);
+
+ switchFlips.put(id+":"+data, new ArrayList<>());
+ switchLoc.put(id+":"+data, pos);
}
}
+ switchLoc.put("mainStream", ((OffsetPoint) getDungeonRoom().getDungeonRoomInfo().getProperties().get("water-lever")).getBlockPos(getDungeonRoom()));
+ switchFlips.put("mainStream", new ArrayList<>());
}
+ private void buildNodes(boolean switchfips) {
+ List<OffsetPoint> frontPoints = frontBoard.getOffsetPointList();
+ List<OffsetPoint> backPoints = backBoard.getOffsetPointList();
+
+ nodes = new Simulator.Node[25][19];
+ waterNodeStart = new Simulator.Pt(9, 0);
+ for (int x = 0; x < 19; x++) {
+ for (int y = 0; y < 25; y++) {
+ OffsetPoint front = frontPoints.get(x *25 +y);
+ OffsetPoint back = backPoints.get(x * 25 +y);
+
+ ptMapping.put(new Simulator.Pt(x,y), front.getBlockPos(getDungeonRoom()));
+ int frontId = Block.getIdFromBlock(front.getBlock(getDungeonRoom()));
+ int backId = Block.getIdFromBlock(back.getBlock(getDungeonRoom()));
+ int frontData = front.getData(getDungeonRoom());
+ int backData = back.getData(getDungeonRoom());
+
+ if (switchfips) {
+ String switchD;
+
+ if (switchFlips.containsKey(switchD = (backId + ":" + backData)) || switchFlips.containsKey(switchD = (frontId + ":" + frontData))) {
+ switchFlips.get(switchD).add(new Simulator.Pt(x, y));
+ }
+ }
+
+ if (frontId == 0 || frontId == 8 /*flowing*/|| frontId == 9) {
+ if (y == 24) {
+ OffsetPoint pos;
+ if (x != 0) {
+ pos = frontPoints.get((x-1)*25+y);
+ } else {
+ pos = frontPoints.get((x+1) * 25 +y);
+ }
+
+ int id = Block.getIdFromBlock(pos.getBlock(getDungeonRoom()));
+ int data= pos.getData(getDungeonRoom());
+ waterNodeEnds.put(id+":"+data, new Simulator.Pt(x,y));
+ }
+
+ nodes[y][x] = new Simulator.Node(frontId != 0 ? frontData >= 8 ? 8 : 8-frontData : 0,
+ frontId == 0 ? Simulator.NodeType.AIR :
+ y == 0 ? Simulator.NodeType.SOURCE :
+ Simulator.NodeType.WATER, false);
+ } else {
+ nodes[y][x] = new Simulator.Node(0, Simulator.NodeType.BLOCK, false);
+ }
+ }
+ }
+ if (switchfips) {
+ switchFlips.get("mainStream").add(waterNodeStart);
+ }
+ }
+ private void targetDoors() {
+ targetDoors.clear();
+ for (OffsetPoint offsetPoint : doorsClosed.getOffsetPointList()) {
+ if (offsetPoint.getBlock(getDungeonRoom()) != Blocks.air) {
+ targetDoors.add(Block.getIdFromBlock(offsetPoint.getBlock(getDungeonRoom()))+":"+offsetPoint.getData(getDungeonRoom()));
+ }
+ }
+ }
+
+ Simulator.Node[][] lastCopy = null;
+
+ private int idx = 0;
@Override
public void tick() {
super.tick();
if (!FeatureRegistry.SOLVER_WATERPUZZLE.isEnabled()) return;
if (!argumentsFulfilled) return;
try {
- waterBoard.tick();
+ buildNodes(false);
+ targetDoors();
+
+ Simulator.Node[][] copy = Simulator.clone(nodes);
+ boolean changed = !Arrays.deepEquals(lastCopy, copy);
+ lastCopy = copy;
+ if (!changed) {
+ if ((System.currentTimeMillis() - lastUnstable) > 1000)
+ lastStable = System.currentTimeMillis();
+ } else {
+ lastUnstable = System.currentTimeMillis();
+ }
+ Simulator.simulateTicks(nodes);
+ if ((System.currentTimeMillis() - lastUnstable) > 1000) {
+ if (t == null || !t.isAlive()) {
+ t = new Thread(() -> {
+ try {
+ List<Simulator.Pt> targets = targetDoors.stream().map(waterNodeEnds::get).collect(Collectors.toList());
+ List<Simulator.Pt> nonTargets = waterNodeEnds.values().stream().filter(a -> !targets.contains(a)).collect(Collectors.toList());
+
+ WaterPathfinder waterPathfinder = new WaterPathfinder(copy, targets, nonTargets, switchFlips);
+ WaterPathfinder.NodeNode nodeNode = waterPathfinder.pathfind();
+ LinkedList<WaterPathfinder.NodeNode> solution = new LinkedList<>();
+ if (nodeNode.getParentToMeAction() != null)
+ solution.addFirst(nodeNode);
+ while (nodeNode.getParent() != null) {
+ nodeNode = nodeNode.getParent();
+ if (nodeNode.getParentToMeAction() != null)
+ solution.addFirst(nodeNode);
+ }
+ this.solutionList = solution;
+ idx = 0;
+ lastStable = System.currentTimeMillis();
+ } catch (Exception e) {
+ lastCopy = null;
+ }
+ });
+ t.start();
+ }
+ }
+
+
+
+ if (solutionList != null && solutionList.size() > 0) {
+ while (System.currentTimeMillis() - lastStable > (long) (idx) * 2500 + 250) { // water flows 5 ticks/s
+ idx ++;
+ }
+ }
} catch (Exception e) {
e.printStackTrace();
}
@@ -84,33 +240,30 @@ public class RoomProcessorWaterPuzzle extends GeneralRoomProcessor {
super.drawWorld(partialTicks);
if (!FeatureRegistry.SOLVER_WATERPUZZLE.isEnabled()) return;
if (!argumentsFulfilled) return;
- if (waterBoard == null) return;
-
- Route route = waterBoard.getCurrentRoute();
- if (route != null) {
- int j = 1;
- for (int i = 0; i < route.getConditionList().size(); i++) {
- LeverState condition = route.getConditionList().get(i);
- if (condition == null) continue;
- SwitchData switchData = waterBoard.getValidSwitches().get(condition.getBlockId());
- if (switchData.getCurrentState(getDungeonRoom().getContext().getWorld()) != condition.isRequiredState()) {
-
- RenderUtils.highlightBlock(switchData.getSwitchLoc(), new Color(0,255,0,50), partialTicks, true);
- RenderUtils.drawTextAtWorld("#"+j,switchData.getSwitchLoc().getX(), switchData.getSwitchLoc().getY()+1, switchData.getSwitchLoc().getZ(), 0xFF000000,0.1f, false, false, partialTicks);
- RenderUtils.drawTextAtWorld(condition.isRequiredState() ? "on":"off",switchData.getSwitchLoc().getX(), switchData.getSwitchLoc().getY(), switchData.getSwitchLoc().getZ(), 0xFF000000,0.1f, false, false, partialTicks);
- j++;
+ for (int y = 0; y < nodes.length; y++) {
+ for (int x = 0; x < nodes[y].length; x++) {
+ Simulator.Node n = nodes[y][x];
+ if (n.getNodeType().isWater()) {
+ RenderUtils.highlightBlock(ptMapping.get(new Simulator.Pt(x,y)), new Color(0, 255, 0, 50), partialTicks, true);
}
}
- for (WaterNode node : route.getNodes()) {
- RenderUtils.highlightBlock(node.getBlockPos(), new Color(0,255,255,50), partialTicks, true);
- }
}
- List<BlockPos> targets = waterBoard.getTarget();
- if (targets != null) {
- for (BlockPos target : targets) {
- RenderUtils.highlightBlock(target, new Color(0,255,255,100), partialTicks, true);
+
+ if (solutionList.size() > 0) {
+ for (int i = idx; i < solutionList.size(); i++) {
+
+ String key = solutionList.get(i).getParentToMeAction().getKey();
+ if (!key.equals("nothing")) {
+ BlockPos pos = switchLoc.get(key);
+ // target:
+ long target = lastStable + 2500L * i;
+
+ double time = (target-System.currentTimeMillis()) / 1000.0 + 0.051;
+ RenderUtils.drawTextAtWorld(String.format("%.1f", time)+"s", pos.getX()+0.5f, pos.getY()+(i-idx)*0.5f - 0.5f, pos.getZ()+0.5f,
+ time < 0.5 ? 0xFF00FF00 : 0xFFFF5500, 0.05f, false, false, partialTicks);
+ }
}
- RenderUtils.highlightBlock(waterBoard.getToggleableMap().get("mainStream").getBlockPos(), new Color(0,255,0,255), partialTicks, true);
+
}
}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/Route.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/Route.java
deleted file mode 100755
index a9f73ae2..00000000
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/Route.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle;
-
-import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.nodes.WaterNodeEnd;
-import lombok.Data;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.*;
-
-@Data
-public class Route implements Cloneable, Comparable {
- private Set<WaterNode> nodes = new LinkedHashSet<WaterNode>();
- private List<LeverState> conditionList = new ArrayList<LeverState>();
- private Set<WaterNodeEnd> endingNodes = new HashSet<WaterNodeEnd>();
-
-
- private int matches = 0;
- private int stateFlops = 0;
- private int notMatches = 0;
-
- public double calculateCost() {
- return (1.0/matches) * 50 + stateFlops * 20 + notMatches * 10000;
- }
-
- @Override
- protected Route clone() {
- Route r = new Route();
- r.getNodes().addAll(nodes);
- r.getConditionList().addAll(conditionList);
- r.getEndingNodes().addAll(endingNodes);
- return r;
- }
-
- @Override
- public int compareTo(@NotNull Object o) {
- if (o instanceof Route) {
- double var0 = calculateCost();
- double var1 = ((Route)o).calculateCost();
- return Double.compare(var0, var1);
- }
- return 0;
- }
-}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/Simulator.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/Simulator.java
new file mode 100644
index 00000000..085abf1c
--- /dev/null
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/Simulator.java
@@ -0,0 +1,257 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+
+import java.util.List;
+import java.util.Scanner;
+
+public class Simulator {
+
+ @AllArgsConstructor @Getter
+ public enum NodeType {
+ BLOCK(false), AIR(false), WATER(true), SOURCE(true);
+
+ private boolean water;
+ }
+
+ @Data @AllArgsConstructor
+ public static class Node {
+ private int waterLevel;
+ private NodeType nodeType;
+ private boolean update;
+ }
+ @Getter @AllArgsConstructor @Data
+ public static class Pt {
+ private final int x, y;
+
+ public Pt up() {return new Pt(x, y-1);}
+ public Pt down() {return new Pt(x, y+1);}
+ public Pt left() {return new Pt(x-1, y);}
+ public Pt right() {return new Pt(x+1, y);}
+
+ public boolean check(int w, int h) {
+ return x < 0 || y < 0 || x >= w || y >= h;
+ }
+
+ public Node get(Node[][] nodes) {
+ if (check(nodes[0].length, nodes.length)) {
+ return new Node(0, NodeType.BLOCK, false);
+ }
+ return nodes[y][x];
+ }
+
+ public void set(Node[][] nodes, NodeType nodeType) {
+ get(nodes).nodeType = nodeType;
+ get(nodes).waterLevel = 0;
+ get(nodes).update = true;
+ }
+
+ public int getFlowDirection(Node[][] nodes) {
+ int right = 0;
+ Pt rightPt = this.right();
+ while (true) {
+ right++;
+ if (right == 8) {
+ right = 999; break;
+ }
+ if (rightPt.get(nodes).nodeType == NodeType.BLOCK) {
+ right = 999; break;
+ }
+ if (rightPt.down().get(nodes).nodeType != NodeType.BLOCK) {
+ break;
+ }
+
+ rightPt = rightPt.right();
+ }
+ int left = 0;
+
+ Pt leftPt = this.left();
+ while (true) {
+ left++;
+ if (left == 8) {
+ left = 999; break;
+ }
+ if (leftPt.get(nodes).nodeType == NodeType.BLOCK) {
+ left = 999; break;
+ }
+ if (leftPt.down().get(nodes).nodeType != NodeType.BLOCK) {
+ break;
+ }
+
+ leftPt = leftPt.left();
+ }
+
+ if (left == right) return 0;
+ if (left > right) return 1;
+ return -1;
+ }
+
+ public boolean shouldUpdate(Node[][] nodes) {
+ return get(nodes).update || right().get(nodes).update
+ || left().get(nodes).update
+ || up().get(nodes).update
+ || down().get(nodes).update;
+ }
+ }
+ // if there is waterLevel bigger coming nearby, make water
+ // if there is waterLevel bigger coming nearby, delete water
+ //
+ public static void simulateTicks(Node[][] nodes) {
+ while(simulateSingleTick(nodes));
+ }
+
+ public static Node[][] clone(Node[][] nodes) {
+ Node[][] newNodes = new Node[nodes.length][nodes[0].length];
+
+ for (int y = 0; y < nodes.length; y++) {
+ for (int x = 0; x < nodes[y].length; x++) {
+ newNodes[y][x] = new Node(nodes[y][x].waterLevel, nodes[y][x].nodeType, nodes[y][x].update);
+ }
+ }
+ return newNodes;
+ }
+
+ public static boolean doTick(Node[][] nodes, Node[][] nodesNew, Pt pt) {
+ int y = pt.y, x = pt.x;
+ Node prev = pt.get(nodes);
+ int maxWaterLv = Math.max(0, prev.nodeType == NodeType.SOURCE ? 8 : prev.waterLevel - 1);
+ if (prev.nodeType == NodeType.AIR || prev.nodeType == NodeType.WATER) {
+ if (pt.up().get(nodes).nodeType.isWater()) {
+ maxWaterLv = 8;
+ }
+ if (pt.left().get(nodes).nodeType.isWater()) {
+ boolean isSource = pt.left().get(nodes).nodeType == NodeType.SOURCE;
+ NodeType bottomLeft = pt.left().down().get(nodes).nodeType;
+ if (prev.nodeType == NodeType.WATER // if was water
+ || (pt.left().shouldUpdate(nodes) && (bottomLeft == NodeType.BLOCK || (isSource && bottomLeft != NodeType.AIR)) && pt.left().getFlowDirection(nodes) >= 0)) {
+ maxWaterLv = Math.max(maxWaterLv, pt.left().get(nodes).waterLevel - 1);
+ }
+ }
+ if (pt.right().get(nodes).nodeType.isWater()) {
+ boolean isSource = pt.right().get(nodes).nodeType == NodeType.SOURCE;
+ NodeType bottomRight = pt.right().down().get(nodes).nodeType;
+ if (prev.nodeType == NodeType.WATER
+ || (pt.right().shouldUpdate(nodes) && (bottomRight == NodeType.BLOCK || (isSource && bottomRight != NodeType.AIR)) && pt.right().getFlowDirection(nodes) <= 0))
+ maxWaterLv = Math.max(maxWaterLv, pt.right().get(nodes).waterLevel - 1);
+ }
+ }
+
+ nodesNew[y][x] = new Node(prev.waterLevel, prev.nodeType, false);
+ nodesNew[y][x].setWaterLevel(maxWaterLv);
+ if (maxWaterLv == 0 && nodesNew[y][x].nodeType == NodeType.WATER)
+ nodesNew[y][x].setNodeType(NodeType.AIR);
+ else if (maxWaterLv > 0 && nodesNew[y][x].nodeType == NodeType.AIR)
+ nodesNew[y][x].setNodeType(NodeType.WATER);
+
+ if (prev.nodeType != nodesNew[y][x].nodeType || prev.waterLevel != nodesNew[y][x].waterLevel) {
+ nodesNew[y][x].update = true;
+ }
+ return nodesNew[y][x].update;
+ }
+ public static boolean simulateSingleTick(Node[][] nodes) {
+ Node[][] nodesNew = new Node[nodes.length][nodes[0].length];
+ boolean update = false;
+ for (int y = 0; y < nodes.length; y++) {
+ for (int x = 0; x < nodes[y].length; x++) {
+ Pt pt = new Pt(x,y);
+
+
+ if (doTick(nodes, nodesNew, pt)) update =true;
+
+ if ( pt.get(nodesNew).waterLevel - pt.get(nodes).waterLevel > 0 && pt.get(nodes).nodeType == NodeType.WATER && pt.get(nodesNew).nodeType == NodeType.WATER) {
+ Node prev = pt.get(nodes);
+
+ nodes[y][x] = nodesNew[y][x];
+
+ if (!pt.left().check(nodes[0].length, nodes.length))
+ doTick(nodes, nodesNew, pt.left());
+ if (!pt.right().check(nodes[0].length, nodes.length))
+ doTick(nodes, nodesNew, pt.right());
+
+ nodes[y][x] = prev;
+ }
+ }
+ }
+
+ for (int y = 0; y < nodesNew.length; y++) {
+ for (int x = 0; x < nodesNew[y].length; x++) {
+ nodes[y][x] = nodesNew[y][x];
+ }
+ }
+ return update;
+ }
+
+ public static void print(Node[][] nodes) {
+ for (int y = 0; y < nodes.length; y++) {
+ for (int x = 0; x < nodes[y].length; x++) {
+ NodeType type = nodes[y][x].nodeType;
+ int cnt = nodes[y][x].waterLevel;
+ if (type == NodeType.BLOCK) {
+ System.out.print("X");
+ } else if (type == NodeType.AIR) {
+ System.out.print(" ");
+ } else if (type == NodeType.WATER) {
+ System.out.print(cnt);
+ } else {
+ System.out.print("W");
+ }
+ }
+ System.out.println();
+ }
+ System.out.println("-----------------");
+ }
+
+ // New waterboard simulator pog
+ public static void main(String[] args) {
+ NodeType[][] nodeTypes = {
+ {NodeType.BLOCK, NodeType.BLOCK, NodeType.BLOCK, NodeType.BLOCK, NodeType.BLOCK, NodeType.BLOCK, NodeType.AIR, NodeType.SOURCE, NodeType.BLOCK},
+ {NodeType.AIR, NodeType.AIR, NodeType.AIR, NodeType.AIR, NodeType.AIR , NodeType.AIR, NodeType.AIR, NodeType.AIR, NodeType.AIR },
+ {NodeType.AIR, NodeType.AIR, NodeType.AIR, NodeType.AIR, NodeType.AIR , NodeType.AIR, NodeType.AIR, NodeType.AIR, NodeType.AIR },
+ {NodeType.AIR, NodeType.AIR, NodeType.AIR, NodeType.AIR, NodeType.AIR , NodeType.AIR, NodeType.AIR, NodeType.AIR, NodeType.AIR },
+ {NodeType.BLOCK, NodeType.AIR, NodeType.AIR, NodeType.AIR, NodeType.AIR , NodeType.AIR, NodeType.AIR, NodeType.AIR, NodeType.AIR }
+ };
+
+ Node[][] nodes = new Node[nodeTypes.length][nodeTypes[0].length];
+ for (int y = 0; y < nodes.length; y++) {
+ for (int x = 0; x < nodes[y].length; x++) {
+ nodes[y][x] = new Node(0, nodeTypes[y][x], false);
+ if (nodeTypes[y][x] == NodeType.SOURCE) {
+ nodes[y][x].update = true;
+ nodes[y][x].waterLevel = 8;
+ }
+ }
+ }
+ Scanner scanner = new Scanner(System.in);
+ while(true) {
+ print(nodes);
+ while(simulateSingleTick(nodes))
+ print(nodes);
+
+ int x = scanner.nextInt();
+ int y= scanner.nextInt();
+ nodes[y][x] = new Node(0,
+ nodes[y][x].nodeType == NodeType.BLOCK ?
+ NodeType.AIR : NodeType.BLOCK, true);
+ }
+ }
+}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/SwitchData.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/SwitchData.java
deleted file mode 100755
index 881716d8..00000000
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/SwitchData.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle;
-
-import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.nodes.WaterNodeStart;
-import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.nodes.WaterNodeToggleable;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import net.minecraft.util.BlockPos;
-import net.minecraft.world.World;
-
-@Data
-@AllArgsConstructor
-public class SwitchData {
- private WaterBoard waterBoard;
-
- private BlockPos switchLoc;
- private BlockPos blockLoc;
-
- private String blockId;
-
- public boolean getCurrentState(World w) {
- WaterNode waterNode = waterBoard.getToggleableMap().get(blockId);
- if (waterNode instanceof WaterNodeStart)
- return ((WaterNodeStart) waterNode).isTriggered(w);
- else if (waterNode instanceof WaterNodeToggleable)
- return ((WaterNodeToggleable) waterNode).isTriggered(w);
- return false;
- }
-}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/WaterBoard.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/WaterBoard.java
deleted file mode 100755
index eece3057..00000000
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/WaterBoard.java
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle;
-
-import kr.syeyoung.dungeonsguide.dungeon.data.OffsetPoint;
-import kr.syeyoung.dungeonsguide.dungeon.data.OffsetPointSet;
-import kr.syeyoung.dungeonsguide.mod.DungeonsGuide;
-import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.nodes.*;
-import lombok.Getter;
-import net.minecraft.block.Block;
-import net.minecraft.block.BlockLever;
-import net.minecraft.init.Blocks;
-import net.minecraft.util.BlockPos;
-import net.minecraft.util.EnumFacing;
-import net.minecraft.util.Tuple;
-import net.minecraft.world.World;
-
-import java.util.*;
-
-public class WaterBoard {
- @Getter
- WaterNode[][] board;
- RoomProcessorWaterPuzzle waterPuzzle;
-
- private final OffsetPointSet frontPlate;
- private final OffsetPointSet backPlate;
- private final OffsetPointSet levers;
- private final OffsetPointSet doors;
- private final OffsetPoint lever;
-
- @Getter
- private final List<SwitchData> switchData = new ArrayList<SwitchData>();
- @Getter
- private final Map<String, SwitchData> validSwitches = new HashMap<String, SwitchData>();
-
- private WaterNodeStart waterNodeStart;
- private final Map<String, WaterNodeEnd> waterNodeEndMap = new HashMap<String, WaterNodeEnd>();
-
- @Getter
- private final Map<String, WaterNode> toggleableMap = new HashMap<String, WaterNode>();
-
- @Getter
- private Set<String> reqOpen = new HashSet<String>();
- @Getter
- private Route currentRoute;
- @Getter
- private List<BlockPos> target;
- @Getter
- private List<String> target2;
-
- public WaterBoard(RoomProcessorWaterPuzzle roomProcessorWaterPuzzle, OffsetPointSet frontPlate, OffsetPointSet backPlate, OffsetPointSet levers, OffsetPointSet doors, OffsetPoint leverMain) {
- this.waterPuzzle = roomProcessorWaterPuzzle;
- this.frontPlate = frontPlate;
- this.backPlate = backPlate;
- this.levers = levers;
- this.doors = doors;
- this.lever = leverMain;
-
- buildLeverStates();
- buildNodes();
- }
-
- private void buildLeverStates(){
- for (OffsetPoint offsetPoint : levers.getOffsetPointList()) {
- if (offsetPoint.getBlock(waterPuzzle.getDungeonRoom()) == Blocks.lever){
- BlockPos pos = offsetPoint.getBlockPos(waterPuzzle.getDungeonRoom());
- World w= waterPuzzle.getDungeonRoom().getContext().getWorld();
- BlockLever.EnumOrientation enumOrientation = w.getBlockState(pos).getValue(BlockLever.FACING);
- EnumFacing enumFacing = enumOrientation.getFacing();
- BlockPos newPos = pos.add(-enumFacing.getDirectionVec().getX(),0,-enumFacing.getDirectionVec().getZ());
-
- int id = Block.getIdFromBlock(w.getChunkFromBlockCoords(newPos).getBlock(newPos));
- int data = w.getChunkFromBlockCoords(newPos).getBlockMetadata(newPos);
-
- SwitchData sw;
- switchData.add(sw = new SwitchData(this, pos,newPos,id+":"+data));
- validSwitches.put(id+":"+data, sw);
- }
- }
- SwitchData sw;
- switchData.add(sw = new SwitchData(this, lever.getBlockPos(waterPuzzle.getDungeonRoom()),lever.getBlockPos(waterPuzzle.getDungeonRoom()).add(0,-1,0),"mainStream"));
- validSwitches.put("mainStream", sw);
- }
-
- public void tick() {
- Set<String> doorsToOpen = new HashSet<String>();
- for (OffsetPoint offsetPoint : doors.getOffsetPointList()) {
- Block b =offsetPoint.getBlock(waterPuzzle.getDungeonRoom());
- if (b != Blocks.air) {
- doorsToOpen.add(Block.getIdFromBlock(b)+":"+offsetPoint.getData(waterPuzzle.getDungeonRoom()));
- }
- }
-// if (!(reqOpen.containsAll(doorsToOpen) && doorsToOpen.containsAll(reqOpen))) {
- reqOpen = doorsToOpen;
- if (doorsToOpen.size() != 0) {
- Set<WaterNodeEnd> ends = new HashSet<WaterNodeEnd>();
- for (String s : doorsToOpen) {
- ends.add(waterNodeEndMap.get(s));
- }
- currentRoute = getBestRoute(ends);
-// {
-//
-// Set<LeverState> currentState = new HashSet<LeverState>();
-// World w = waterPuzzle.getDungeonRoom().getContext().getWorld();
-// for (SwitchData switchDatum : this.switchData) {
-// currentState.add(new LeverState(switchDatum.getBlockId(), switchDatum.getCurrentState(w)));
-// }
-// currentRoute = simulate(currentState);
-// }
-
- target = new ArrayList<BlockPos>();
- target2 = new ArrayList<String>();
- if (currentRoute != null) {
- for (WaterNodeEnd endingNode : currentRoute.getEndingNodes()) {
- target.add(endingNode.getBlockPos());
- target2.add(endingNode.getResultId());
- }
- }
- }
-// }
- }
-
- public Route getBestRoute(Set<WaterNodeEnd> potentialEnds) {
- int totalStates = (int) Math.pow(2, validSwitches.size() - 1);
- List<SwitchData> switchData = new ArrayList<SwitchData>();
- Set<LeverState> currentState = new HashSet<LeverState>();
- World w = waterPuzzle.getDungeonRoom().getContext().getWorld();
- for (SwitchData switchDatum : this.switchData) {
- if (!switchDatum.getBlockId().equals("mainStream")) {
- switchData.add(switchDatum);
- }
- currentState.add(new LeverState(switchDatum.getBlockId(), switchDatum.getCurrentState(w)));
- }
- PriorityQueue<Route> routes = new PriorityQueue<Route>();
-
- for (int i = 0; i < totalStates; i++) {
- Set<LeverState> states = new HashSet<LeverState>();
- for (int i1 = 0; i1 < switchData.size(); i1++) {
- states.add(new LeverState(switchData.get(i1).getBlockId(), ((i >> i1) & 0x1) > 0));
- }
- states.add(new LeverState("mainStream", true));
-
- Route r = simulate(states);
-
- for (LeverState leverState : currentState) {
- if (!states.contains(leverState))
- r.setStateFlops(r.getStateFlops() + 1);
- }
- for (WaterNodeEnd potentialEnd : r.getEndingNodes()) {
- if (potentialEnds.contains(potentialEnd)) {
- r.setMatches(r.getMatches() + 1);
- } else {
- r.setNotMatches(r.getNotMatches() + 1);
- }
- }
- if (r.getMatches() > 0)
- routes.add(r);
- }
-
-
- return routes.peek();
- }
-
- public Route simulate(Set<LeverState> leverStates) {
- leverStates.add(null);
- Route r = new Route();
- final Queue<WaterNode> toGoDownTo = new LinkedList<WaterNode>();
- Set<WaterNode> searched = new HashSet<WaterNode>();
- Set<LeverState> waterBlockingStates = new HashSet<LeverState>();
- World w = waterPuzzle.getDungeonRoom().getContext().getWorld();
-// toGoDownTo.add(getNodeAt(waterNodeStart.getX(), waterNodeStart.getY() + 1));
- {
- Queue<Tuple<WaterNode, Boolean>> toGo = new LinkedList<>();
- toGo.add(new Tuple<>(waterNodeStart, true));
- toGoDownTo.add(getNodeAt(waterNodeStart.getX(), waterNodeStart.getY() + 1));
- Set<WaterNode> visited = new HashSet<>();
- while (!toGo.isEmpty()) {
- Tuple<WaterNode, Boolean> waterNode = toGo.poll();
- if (waterNode.getFirst() == null) continue;
- if (visited.contains(waterNode.getFirst())) continue;
- if (!waterNode.getFirst().canWaterGoThrough()) continue;
- if (waterNode.getFirst() instanceof WaterNodeEnd) continue;
- visited.add(waterNode.getFirst());
-
- boolean water = waterNode.getFirst().isWaterFilled(w);
- if (water && !waterNode.getSecond()) {
- toGoDownTo.add(getNodeAt(waterNode.getFirst().getX(), waterNode.getFirst().getY()));
- }
-
- int x = waterNode.getFirst().getX(), y = waterNode.getFirst().getY();
- toGo.add(new Tuple<>(getNodeAt(x+1, y), water));
- toGo.add(new Tuple<>(getNodeAt(x-1, y), water));
- toGo.add(new Tuple<>(getNodeAt(x, y+1), water));
- }
- }
- while (!toGoDownTo.isEmpty()) {
- WaterNode asd = toGoDownTo.poll();
- if (asd == null) continue;
- if (searched.contains(asd)) continue;
- searched.add(asd);
-
- if (asd instanceof WaterNodeEnd) {
- if (!asd.isWaterFilled(w))
- r.getEndingNodes().add((WaterNodeEnd) asd);
- continue;
- }
-
- r.getNodes().add(asd);
-
- if (asd.isWaterFilled(w) && (
- (getNodeAt(asd.getX() + 1, asd.getY()) != null && getNodeAt(asd.getX() + 1, asd.getY()).isWaterFilled(w))
- || (getNodeAt(asd.getX() - 1, asd.getY()) != null && getNodeAt(asd.getX() - 1, asd.getY()).isWaterFilled(w)))) {
- boolean followWater = getNodeAt(asd.getX() - 1, asd.getY()) != null && leverStates.contains(getNodeAt(asd.getX() - 1, asd.getY()).getCondition())
- && getNodeAt(asd.getX() - 2, asd.getY()) != null && leverStates.contains(getNodeAt(asd.getX() - 2, asd.getY()).getCondition());
- for (int i = asd.getX(); i < asd.getX() + 8; i++) {
- WaterNode nodeHere = getNodeAt(i, asd.getY());
- if (nodeHere == null) break;
- if (followWater && !nodeHere.isWaterFilled(w)) break;
- if (!nodeHere.canWaterGoThrough()) break;
- if (!leverStates.contains(nodeHere.getCondition()) && !nodeHere.isWaterFilled(w)) break;
- if (nodeHere.getCondition() != null && leverStates.contains(nodeHere.getCondition().invert()) && nodeHere.isWaterFilled(w)) waterBlockingStates.add(nodeHere.getCondition().invert());
- WaterNode down = getNodeAt(i, asd.getY() + 1);
- if (i != asd.getX())
- followWater = nodeHere.isWaterFilled(w) && (down == null || (down.canWaterGoThrough() && leverStates.contains(down.getCondition())));
- r.getNodes().add(nodeHere);
- if (down != null && down.canWaterGoThrough() && down.getCondition() != null && leverStates.contains(down.getCondition().invert())) {
- waterBlockingStates.add(down.getCondition().invert());
- }
- if (down != null && ((down.canWaterGoThrough() && leverStates.contains(down.getCondition())) || down.isWaterFilled(w))) {
- toGoDownTo.add(down);
- if (!followWater) break;
- }
- }
- followWater = getNodeAt(asd.getX() +1, asd.getY()) != null && leverStates.contains(getNodeAt(asd.getX() + 1, asd.getY()).getCondition())
- && getNodeAt(asd.getX() +2, asd.getY()) != null && leverStates.contains(getNodeAt(asd.getX() + 2, asd.getY()).getCondition());
- for (int i = asd.getX(); i > asd.getX() - 8; i--) {
- WaterNode nodeHere = getNodeAt(i, asd.getY());
- if (nodeHere == null) break;
- if (followWater && !nodeHere.isWaterFilled(w)) break;
- if (!nodeHere.canWaterGoThrough()) break;
- if (!leverStates.contains(nodeHere.getCondition()) && !nodeHere.isWaterFilled(w)) break;
- if (nodeHere.getCondition() != null && leverStates.contains(nodeHere.getCondition().invert()) && nodeHere.isWaterFilled(w)) waterBlockingStates.add(nodeHere.getCondition().invert());
- WaterNode down = getNodeAt(i, asd.getY() + 1);
- if (i != asd.getX())
- followWater = nodeHere.isWaterFilled(w) && (down == null || (down.canWaterGoThrough() && leverStates.contains(down.getCondition())));
- r.getNodes().add(nodeHere);
- if (down != null && down.canWaterGoThrough() && down.getCondition() != null && leverStates.contains(down.getCondition().invert())) {
- waterBlockingStates.add(down.getCondition().invert());
- }
- if (down != null && ((down.canWaterGoThrough() && leverStates.contains(down.getCondition())) || down.isWaterFilled(w))) {
- toGoDownTo.add(down);
- if (!followWater) break;
- }
- }
- } else {
- int minDistToDropRight = 9999;
- for (int i = asd.getX(); i < asd.getX() + 8; i++) {
- WaterNode nodeHere = getNodeAt(i, asd.getY());
- if (nodeHere == null) break;
- if (!nodeHere.canWaterGoThrough()) break;
- if (!leverStates.contains(nodeHere.getCondition()) && !nodeHere.isWaterFilled(w)) break;
- WaterNode down = getNodeAt(i, asd.getY() + 1);
- if (down != null && ((down.canWaterGoThrough() && leverStates.contains(down.getCondition())))) {
- int dist = i - asd.getX();
- if (dist < minDistToDropRight)
- minDistToDropRight = dist;
- break;
- }
- }
- int minDistToDropLeft = 9999;
- for (int i = asd.getX(); i > asd.getX() - 8; i--) {
- WaterNode nodeHere = getNodeAt(i, asd.getY());
- if (nodeHere == null) break;
- if (!nodeHere.canWaterGoThrough()) break;
- if (!leverStates.contains(nodeHere.getCondition()) && !nodeHere.isWaterFilled(w)) break;
- WaterNode down = getNodeAt(i, asd.getY() + 1);
- if (down != null && ((down.canWaterGoThrough() && leverStates.contains(down.getCondition())))) {
- int dist = asd.getX() - i;
- if (dist < minDistToDropLeft)
- minDistToDropLeft = dist;
- break;
- }
- }
-
- int min = Math.min(minDistToDropRight, minDistToDropLeft);
- if (min == 9999) continue;
- if (minDistToDropRight == min) {
- for (int i = asd.getX(); i <= asd.getX() + minDistToDropRight; i++) {
- WaterNode nodeHere = getNodeAt(i, asd.getY());
- if (nodeHere.getCondition() != null && leverStates.contains(nodeHere.getCondition().invert()) && nodeHere.isWaterFilled(w)) waterBlockingStates.add(nodeHere.getCondition().invert());
- r.getNodes().add(nodeHere);
- WaterNode down = getNodeAt(i, asd.getY() + 1);
- if (down != null && ((down.canWaterGoThrough() && leverStates.contains(down.getCondition())) || down.isWaterFilled(w))) {
- toGoDownTo.add(down);
- }
- if (down != null && down.canWaterGoThrough() && down.getCondition() != null && leverStates.contains(down.getCondition().invert())) {
- waterBlockingStates.add(down.getCondition().invert());
- }
- }
- }
- if (minDistToDropLeft == min) {
- for (int i = asd.getX(); i >= asd.getX() - minDistToDropLeft; i--) {
- WaterNode nodeHere = getNodeAt(i, asd.getY());
- if (nodeHere.getCondition() != null && leverStates.contains(nodeHere.getCondition().invert()) && nodeHere.isWaterFilled(w)) waterBlockingStates.add(nodeHere.getCondition().invert());
- r.getNodes().add(nodeHere);
- WaterNode down = getNodeAt(i, asd.getY() + 1);
- if (down != null && ((down.canWaterGoThrough() && leverStates.contains(down.getCondition())) || down.isWaterFilled(w))) {
- toGoDownTo.add(down);
- }
- if (down != null && down.canWaterGoThrough() && down.getCondition() != null && leverStates.contains(down.getCondition().invert())) {
- waterBlockingStates.add(down.getCondition().invert());
- }
- }
- }
- }
- }
- ArrayList<LeverState> state = new ArrayList<LeverState>(waterBlockingStates);
- state.remove(null);
- Collections.sort(state, new Comparator<LeverState>() {
- @Override
- public int compare(LeverState leverState, LeverState t1) {
- int var0 = toggleableMap.get(leverState.getBlockId()).getY();
- int var1 = toggleableMap.get(t1.getBlockId()).getY();
- return var0 < var1 ? -1 : (var0 == var1 ? 0 : 1);
- }
- });
- LinkedList<LeverState> states = new LinkedList<LeverState>(state);
- for (LeverState ls : leverStates) {
- if (!states.contains(ls)) {
- states.add(ls);
- }
- }
- states.remove(null);
-
-
- r.setConditionList(states);
- return r;
- }
-
-
- public WaterNode getNodeAt(int x, int y) {
- if (x < 0 || y < 0) return null;
- if (x >= board[0].length || y >= board.length) return null;
- return board[y][x];
- }
-
- private void buildNodes() {
- List<OffsetPoint> frontPoints = frontPlate.getOffsetPointList();
- List<OffsetPoint> backPoints = backPlate.getOffsetPointList();
-
- board = new WaterNode[25][19];
- for (int x = 0; x < 19; x++) {
- for (int y = 0; y < 25; y++) {
- OffsetPoint front = frontPoints.get(x *25 +y);
- OffsetPoint back = backPoints.get(x * 25 +y);
- int frontId = Block.getIdFromBlock(front.getBlock(waterPuzzle.getDungeonRoom()));
- int backId = Block.getIdFromBlock(back.getBlock(waterPuzzle.getDungeonRoom()));
- int frontData = front.getData(waterPuzzle.getDungeonRoom());
- int backData = back.getData(waterPuzzle.getDungeonRoom());
- WaterNode node;
- if (validSwitches.containsKey(backId +":"+backData)) {
- String resId = backId + ":"+backData;
- node = new WaterNodeToggleable(resId, isSwitchActive(validSwitches.get(resId)), front.getBlockPos(waterPuzzle.getDungeonRoom()),x,y);
-
- toggleableMap.put(resId, node);
- } else if (validSwitches.containsKey(frontId +":"+frontData)) {
- String resId = frontId +":"+frontData;
- node = new WaterNodeToggleable(resId, !isSwitchActive(validSwitches.get(resId)), front.getBlockPos(waterPuzzle.getDungeonRoom()),x,y);
-
- toggleableMap.put(resId, node);
- } else if (frontId == 0 || frontId == 8 || frontId == 9) {
- if (y == 24) {
- OffsetPoint pos;
- if (x != 0) {
- pos = frontPoints.get((x-1)*25+y);
- } else {
- pos = frontPoints.get((x+1) * 25 +y);
- }
-
- int id = Block.getIdFromBlock(pos.getBlock(waterPuzzle.getDungeonRoom()));
- int data= pos.getData(waterPuzzle.getDungeonRoom());
- node = new WaterNodeEnd(id+":"+data, front.getBlockPos(waterPuzzle.getDungeonRoom()),x,y);
- waterNodeEndMap.put(id+":"+data, (WaterNodeEnd) node);
- } else if (y == 2 && x == 9) {
- waterNodeStart = (WaterNodeStart) (node = new WaterNodeStart(front.getBlockPos(waterPuzzle.getDungeonRoom()),
- frontId != 0 ^ isSwitchActive(validSwitches.get("mainStream")),x,y));
- } else {
- node = new WaterNodeAir(front.getBlockPos(waterPuzzle.getDungeonRoom()),x,y);
- }
- } else {
- node = new WaterNodeWall(front.getBlockPos(waterPuzzle.getDungeonRoom()),x,y);
- }
- board[y][x] =node;
- }
- }
- toggleableMap.put("mainStream", waterNodeStart);
- }
-
- private boolean isSwitchActive(SwitchData switchData) {
- BlockPos switch2 = switchData.getSwitchLoc();
- World w= waterPuzzle.getDungeonRoom().getContext().getWorld();
- boolean bool = DungeonsGuide.getDungeonsGuide().getBlockCache().getBlockState(switch2).getValue(BlockLever.POWERED);
- return bool;
- }
-
-
-}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/WaterNode.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/WaterNode.java
deleted file mode 100755
index cbcb1cb0..00000000
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/WaterNode.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle;
-
-import net.minecraft.util.BlockPos;
-import net.minecraft.world.World;
-
-public interface WaterNode {
- boolean canWaterGoThrough();
-
- // condition for water go
- LeverState getCondition();
-
- boolean isWaterFilled(World w);
-
- BlockPos getBlockPos();
-
- int getX();
- int getY();
-}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/WaterPathfinder.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/WaterPathfinder.java
new file mode 100644
index 00000000..92b08bd2
--- /dev/null
+++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/WaterPathfinder.java
@@ -0,0 +1,204 @@
+/*
+ * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
+ * Copyright (C) 2023 cyoung06 (syeyoung)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+
+import java.util.*;
+
+public class WaterPathfinder {
+ // A* on waterboard... lol graph search
+ Set<AdvanceAction> availableActions = new HashSet<>();
+
+
+ private State begin;
+ private Map<State, NodeNode> mapping = new HashMap<>();
+
+ private List<Simulator.Pt> targets = new ArrayList<>();
+ private List<Simulator.Pt> nonTargets = new ArrayList<>();
+ private int maxMatch = 0;
+
+ public WaterPathfinder(Simulator.Node[][] begin, List<Simulator.Pt> targets, List<Simulator.Pt> nonTargets, Map<String, List<Simulator.Pt>> switchFlips) {
+ this.targets = targets;
+ this.nonTargets = nonTargets;
+
+ ArrayList<Simulator.Pt> total = new ArrayList();
+ total.addAll(targets);
+ total.addAll(nonTargets);
+ maxMatch = total.size();
+ for (Map.Entry<String, List<Simulator.Pt>> stringListEntry : switchFlips.entrySet()) {
+ availableActions.add(new AdvanceAction(stringListEntry.getValue(), stringListEntry.getKey(), 10, total,
+ 10));
+ }
+
+ availableActions.add(new AdvanceAction(new ArrayList<>(), "nothing", 1, total, 10));
+ this.begin = new State(begin, new int[total.size()]);
+
+ }
+
+ private float fScore(NodeNode node) {
+ int cnt = 0;
+ for (int i = 0; i < node.state.flips.length; i++) {
+ if ((node.state.flips[i] % 2 == 1) != (i < targets.size())) {
+ cnt += 1;
+ }
+ }
+//
+// int smh = node.state.state.length;
+// label: for (int i = node.state.state.length-1; i >= 0; i--) {
+// for (int x = 0; x < node.state.state[i].length; x++) {
+// if (node.state.state[i][x].getNodeType().isWater()) {
+// smh = i;
+// break label;
+// }
+// }
+// }
+// return (cnt) * 20;
+ return cnt * 200; // dijkstra lol
+ }
+ public NodeNode pathfind() {
+ PriorityQueue<NodeNode> nodes = new PriorityQueue<>(Comparator.comparingDouble((NodeNode a) -> a.f).thenComparing(a -> a.g).thenComparing(a->Arrays.deepHashCode(a.state.state)).thenComparing(NodeNode::hashCode));
+ NodeNode start = openNode(begin);
+ start.f = fScore(start);
+ start.g = 0;
+ nodes.add(start);
+ while(!nodes.isEmpty()) {
+ NodeNode node = nodes.poll();
+ if (fScore(node) == 0) return node;
+// System.out.println(nodes.size());
+
+
+ for (AdvanceAction availableAction : availableActions) {
+ State newState = availableAction.generateNew(node.state);
+ if (newState == null) continue;
+ NodeNode newNodeNode = openNode(newState);
+
+ float newG = node.g + availableAction.cost;
+ if (newNodeNode.g > newG) {
+ newNodeNode.g = newG;
+ newNodeNode.f = newNodeNode.g + fScore(newNodeNode) ;// heuristic
+ newNodeNode.parent = node;
+ newNodeNode.parentToMeAction = availableAction;
+
+ nodes.add(newNodeNode);
+ }
+ }
+ }
+ return null;
+ }
+
+ public NodeNode openNode(State state) {
+ if (mapping.containsKey(state)) {
+ return mapping.get(state);
+ }
+ NodeNode nodeNode = new NodeNode(state, null, null, Float.MAX_VALUE, Float.MAX_VALUE);
+ mapping.put(state, nodeNode);
+ return nodeNode;
+ }
+
+ @AllArgsConstructor @Getter
+ public static class State {
+ private final Simulator.Node[][] state;
+ private final int[] flips;
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ State state1 = (State) o;
+
+ return Arrays.deepEquals(state, state1.state) && Arrays.equals(flips, state1.flips);
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.deepHashCode(state) << 31 | Arrays.hashCode(flips);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ for (int y = 0; y < state.length; y++) {
+ for (int x = 0; x < state[y].length; x++) {
+ Simulator.NodeType type = state[y][x].getNodeType();
+ int cnt = state[y][x].getWaterLevel();
+ if (type == Simulator.NodeType.BLOCK) {
+ sb.append("X");
+ } else if (type == Simulator.NodeType.AIR) {
+ sb.append(" ");
+ } else if (type == Simulator.NodeType.WATER) {
+ sb.append(cnt);
+ } else {
+ sb.append("W");
+ }
+ }
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+ }
+
+ @Data @AllArgsConstructor
+ public static class NodeNode {
+ private State state;
+ private NodeNode parent;
+ private AdvanceAction parentToMeAction;
+
+ private float f, g;
+ // dist curr
+ }
+
+
+ @Getter @AllArgsConstructor
+ public static class AdvanceAction {
+ private final List<Simulator.Pt> flips;
+ private final String key;
+ private final float cost;
+ private final List<Simulator.Pt> targets;
+ private final int moves;
+
+ public State generateNew(State from) {
+ Simulator.Node[][] nodes = Simulator.clone(from.state);
+ for (Simulator.Pt flip : flips) {
+ Simulator.Node node = flip.get(nodes);
+ if (node.getNodeType() == Simulator.NodeType.BLOCK) flip.set(nodes, Simulator.NodeType.AIR);
+ else flip.set(nodes, Simulator.NodeType.BLOCK);
+ }
+ Simulator.simulateSingleTick(nodes);
+ for (int i = 0; i < moves; i++) {
+ Simulator.simulateSingleTick(nodes);
+ }
+// if (1==1) return null;
+
+ int[] newFlips = Arrays.copyOf(from.flips, from.flips.length);
+
+ for (int i = 0; i < targets.size(); i++) {
+ Simulator.Pt target = targets.get(i);
+ if (!target.get(from.state).getNodeType().isWater() && target.get(nodes).getNodeType().isWater()) {
+ newFlips[i]++;
+ }
+ }
+
+ return new State(nodes, newFlips);
+ }
+ }
+}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeAir.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeAir.java
deleted file mode 100755
index ffb8b65a..00000000
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeAir.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.nodes;
-
-import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.LeverState;
-import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.WaterNode;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import net.minecraft.block.Block;
-import net.minecraft.init.Blocks;
-import net.minecraft.util.BlockPos;
-import net.minecraft.world.World;
-
-@Data
-@AllArgsConstructor
-public class WaterNodeAir implements WaterNode {
- BlockPos blockPos;
- @Override
- public boolean canWaterGoThrough() {
- return true;
- }
-
- @Override
- public LeverState getCondition() {
- return null;
- }
-
- @Override
- public boolean isWaterFilled(World w) {
- Block b = w.getChunkFromBlockCoords(blockPos).getBlock(blockPos);
- return b == Blocks.water || b == Blocks.flowing_water;
- }
-
- public BlockPos getBlockPos() {
- return blockPos;
- }
-
- private int x,y;
-
- public String toString() {
- return "A";
- }
-}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeEnd.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeEnd.java
deleted file mode 100755
index 22a62a00..00000000
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeEnd.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.nodes;
-
-import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.LeverState;
-import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.WaterNode;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import net.minecraft.block.Block;
-import net.minecraft.init.Blocks;
-import net.minecraft.util.BlockPos;
-import net.minecraft.world.World;
-
-@Data
-@AllArgsConstructor
-public class WaterNodeEnd implements WaterNode {
- private String resultId;
- BlockPos blockPos;
-
- @Override
- public boolean canWaterGoThrough() {
- return true;
- }
-
- @Override
- public LeverState getCondition() {
- return null;
- }
-
- @Override
- public boolean isWaterFilled(World w) {
- Block b = w.getChunkFromBlockCoords(blockPos).getBlock(blockPos);
- return b == Blocks.water || b == Blocks.flowing_water;
- }
-
- public BlockPos getBlockPos() {
- return blockPos;
- }
- private int x,y;
-
- public String toString() {
- return "E";
- }
-}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeStart.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeStart.java
deleted file mode 100755
index e067cf9b..00000000
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeStart.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.nodes;
-
-import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.LeverState;
-import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.WaterNode;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import net.minecraft.block.Block;
-import net.minecraft.init.Blocks;
-import net.minecraft.util.BlockPos;
-import net.minecraft.world.World;
-
-@Data
-@AllArgsConstructor
-public class WaterNodeStart implements WaterNode {
-
- private BlockPos blockPos;
- private boolean isReversed;
-
- @Override
- public boolean canWaterGoThrough() {
- return true;
- }
-
- @Override
- public LeverState getCondition() {
- return new LeverState("mainStream", !isReversed);
- }
-
- @Override
- public boolean isWaterFilled(World w) {
- Block b = w.getChunkFromBlockCoords(blockPos).getBlock(blockPos);
- return b == Blocks.water || b == Blocks.flowing_water;
- }
-
- public boolean isTriggered(World w) {
- return isWaterFilled(w);
- }
-
-
- public BlockPos getBlockPos() {
- return blockPos;
- }
- private int x,y;
-
- public String toString() {
- return "S";
- }
-}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeToggleable.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeToggleable.java
deleted file mode 100755
index 7235e269..00000000
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeToggleable.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.nodes;
-
-import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.LeverState;
-import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.WaterNode;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import net.minecraft.block.Block;
-import net.minecraft.init.Blocks;
-import net.minecraft.util.BlockPos;
-import net.minecraft.world.World;
-
-@Data
-@AllArgsConstructor
-public class WaterNodeToggleable implements WaterNode {
- private String blockId;
- private boolean invert;
-
- BlockPos blockPos;
-
- @Override
- public boolean canWaterGoThrough() {
- return true;
- }
-
- @Override
- public LeverState getCondition() {
- return new LeverState(blockId, invert);
- }
-
-
- @Override
- public boolean isWaterFilled(World w) {
- Block b = w.getChunkFromBlockCoords(blockPos).getBlock(blockPos);
- return b == Blocks.water || b == Blocks.flowing_water;
- }
- private int x,y;
-
- public boolean isTriggered(World w) {
- Block b= w.getChunkFromBlockCoords(blockPos).getBlock(blockPos);
-
- return !(b == Blocks.air || b == Blocks.water || b == Blocks.flowing_water) ^ invert;
- }
-
-
- public BlockPos getBlockPos() {
- return blockPos;
- }
-
-
- public String toString() {
- return "T:"+blockId+(invert ? ":Y":":N");
- }
-}
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeWall.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeWall.java
deleted file mode 100755
index 0f2b9a44..00000000
--- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/roomprocessor/waterpuzzle/nodes/WaterNodeWall.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod
- * Copyright (C) 2021 cyoung06
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.nodes;
-
-import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.LeverState;
-import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.waterpuzzle.WaterNode;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import net.minecraft.block.Block;
-import net.minecraft.init.Blocks;
-import net.minecraft.util.BlockPos;
-import net.minecraft.world.World;
-
-@Data
-@AllArgsConstructor
-public class WaterNodeWall implements WaterNode {
-
- BlockPos blockPos;
- @Override
- public boolean canWaterGoThrough() {
- return false;
- }
-
- @Override
- public LeverState getCondition() {
- return null;
- }
-
-
- @Override
- public boolean isWaterFilled(World w) {
- Block b = w.getChunkFromBlockCoords(blockPos).getBlock(blockPos);
- return b == Blocks.water || b == Blocks.flowing_water;
- }
-
- private int x,y;
-
- public BlockPos getBlockPos() {
- return blockPos;
- }
-
-
- public String toString() {
- return "W";
- }
-}