diff options
21 files changed, 711 insertions, 38 deletions
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/data/OffsetPoint.java b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/data/OffsetPoint.java index ecb3b268..b6497872 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/data/OffsetPoint.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/data/OffsetPoint.java @@ -8,10 +8,11 @@ import net.minecraft.block.Block; import net.minecraft.util.BlockPos; import javax.vecmath.Vector2d; +import java.io.Serializable; @Data @AllArgsConstructor -public class OffsetPoint implements Cloneable { +public class OffsetPoint implements Cloneable, Serializable { private int x; private int y; private int z; diff --git a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/data/OffsetPointSet.java b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/data/OffsetPointSet.java index c33f7af8..9aea7610 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/data/OffsetPointSet.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/data/OffsetPointSet.java @@ -2,11 +2,12 @@ package kr.syeyoung.dungeonsguide.dungeon.data; import lombok.Data; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; @Data -public class OffsetPointSet implements Cloneable{ +public class OffsetPointSet implements Cloneable, Serializable { private List<OffsetPoint> offsetPointList = new ArrayList<OffsetPoint>(); @Override diff --git a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/doorfinder/DoorFinderRegistry.java b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/doorfinder/DoorFinderRegistry.java index 306b1993..0fb3c89a 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/doorfinder/DoorFinderRegistry.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/doorfinder/DoorFinderRegistry.java @@ -8,7 +8,7 @@ public class DoorFinderRegistry { private static final Map<Pattern, StartDoorFinder> doorFinders = new HashMap<Pattern, StartDoorFinder>(); static { - doorFinders.put(Pattern.compile("The Catacombs F[0-9]"), new CatacombDoorFinder()); + doorFinders.put(Pattern.compile("The Catacombs (?:F[0-9]|E)"), new CatacombDoorFinder()); } public static StartDoorFinder getDoorFinder(String dungeonName) { diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomedit/panes/RoomDataDisplayPane.java b/src/main/java/kr/syeyoung/dungeonsguide/roomedit/panes/RoomDataDisplayPane.java index 38d57eef..be517e81 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/roomedit/panes/RoomDataDisplayPane.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomedit/panes/RoomDataDisplayPane.java @@ -76,6 +76,14 @@ public class RoomDataDisplayPane extends MPanel { this.setBounds(new Rectangle(5,5,parentWidth-10,parentHeight-10)); } + @Override + public void keyTyped(char typedChar, int keyCode) { + int[][] blocks = dungeonRoom.getDungeonRoomInfo().getBlocks(); + if (selectedX != -1 && selectedY != -1 && selectedY < blocks.length && selectedX < blocks[0].length) { + dungeonRoom.getDungeonRoomInfo().getBlocks()[selectedY][selectedX] = -1; + } + } + private int lastX; private int lastY; @Override diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/DefaultRoomProcessor.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/DefaultRoomProcessor.java deleted file mode 100644 index 596ebb74..00000000 --- a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/DefaultRoomProcessor.java +++ /dev/null @@ -1,29 +0,0 @@ -package kr.syeyoung.dungeonsguide.roomprocessor; - -import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoom; - -public class DefaultRoomProcessor implements RoomProcessor { - - public DefaultRoomProcessor(DungeonRoom dungeonRoom) { - - } - - @Override - public void tick() { - - } - - @Override - public void drawScreen(float partialTicks) { - - } - - public static class Generator implements RoomProcessorGenerator<DefaultRoomProcessor> { - @Override - public DefaultRoomProcessor createNew(DungeonRoom dungeonRoom) { - - DefaultRoomProcessor defaultRoomProcessor = new DefaultRoomProcessor(dungeonRoom); - return defaultRoomProcessor; - } - } -} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/GeneralRoomProcessor.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/GeneralRoomProcessor.java new file mode 100644 index 00000000..f9472791 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/GeneralRoomProcessor.java @@ -0,0 +1,39 @@ +package kr.syeyoung.dungeonsguide.roomprocessor; + +import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoom; +import kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle.RoomProcessorWaterPuzzle; +import lombok.Getter; +import lombok.Setter; + +public class GeneralRoomProcessor implements RoomProcessor { + + @Getter + @Setter + private DungeonRoom dungeonRoom; + public GeneralRoomProcessor(DungeonRoom dungeonRoom) { + this.dungeonRoom = dungeonRoom; + } + + @Override + public void tick() { + + } + + @Override + public void drawScreen(float partialTicks) { + + } + + @Override + public void drawWorld(float partialTicks) { + + } + + public static class Generator implements RoomProcessorGenerator<GeneralRoomProcessor> { + @Override + public GeneralRoomProcessor createNew(DungeonRoom dungeonRoom) { + GeneralRoomProcessor defaultRoomProcessor = new GeneralRoomProcessor(dungeonRoom); + return defaultRoomProcessor; + } + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/ProcessorFactory.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/ProcessorFactory.java index 3f65c642..23976fbd 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/ProcessorFactory.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/ProcessorFactory.java @@ -1,6 +1,7 @@ package kr.syeyoung.dungeonsguide.roomprocessor; import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoom; +import kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle.RoomProcessorWaterPuzzle; import java.util.HashMap; import java.util.Map; @@ -22,7 +23,8 @@ public class ProcessorFactory { } static { - registerRoomProcessor("default", new DefaultRoomProcessor.Generator()); + registerRoomProcessor("default", new GeneralRoomProcessor.Generator()); registerRoomProcessor("puzzle_blaze_solver", new RoomProcessorBlazeSolver.Generator()); + registerRoomProcessor("puzzle_water_solver", new RoomProcessorWaterPuzzle.Generator()); } } diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessor.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessor.java index ed8a89f7..4498811a 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessor.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessor.java @@ -5,4 +5,5 @@ import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoom; public interface RoomProcessor { void tick(); void drawScreen(float partialTicks); + void drawWorld(float partialTicks); }
\ No newline at end of file diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorBlazeSolver.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorBlazeSolver.java index ec1ed164..54f09010 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorBlazeSolver.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessorBlazeSolver.java @@ -15,20 +15,20 @@ import net.minecraft.util.Vec3; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; +import java.awt.*; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; -public class RoomProcessorBlazeSolver implements RoomProcessor { +public class RoomProcessorBlazeSolver extends GeneralRoomProcessor { - private DungeonRoom dungeonRoom; private boolean highToLow = false; private List<EntityArmorStand> entityList = new ArrayList<EntityArmorStand>(); private EntityArmorStand next; public RoomProcessorBlazeSolver(DungeonRoom dungeonRoom) { - this.dungeonRoom = dungeonRoom; + super(dungeonRoom); Object highToLow = dungeonRoom.getDungeonRoomInfo().getProperties().get("order"); if (highToLow == null) this.highToLow = false; else this.highToLow = (Boolean) highToLow; @@ -36,6 +36,9 @@ public class RoomProcessorBlazeSolver implements RoomProcessor { @Override public void tick() { + super.tick(); + + DungeonRoom dungeonRoom = getDungeonRoom(); World w = dungeonRoom.getContext().getWorld(); final BlockPos low = dungeonRoom.getMin(); final BlockPos high = dungeonRoom.getMax(); @@ -53,7 +56,7 @@ public class RoomProcessorBlazeSolver implements RoomProcessor { for (EntityArmorStand ea : entityList) { String name = ea.getName(); String colorGone = TextUtils.stripColor(name); - String health2 = colorGone.split("/")[1]; + String health2 = TextUtils.keepIntegerCharactersOnly(colorGone.split("/")[1]); try { int heal = Integer.parseInt(health2); if (highToLow && heal > health) { @@ -70,11 +73,14 @@ public class RoomProcessorBlazeSolver implements RoomProcessor { next = semi_target; } + @Override - public void drawScreen(float partialTicks) { + public void drawWorld(float partialTicks) { + super.drawWorld(partialTicks); if (next == null) return; Vec3 pos = next.getPositionEyes(partialTicks); RenderUtils.drawTextAtWorld("NEXT", (float)pos.xCoord, (float)pos.yCoord, (float)pos.zCoord, 0xFFFF0000, 3, true, false, partialTicks); + RenderUtils.highlightBlock(next.getPosition(), new Color(0,255,0,50), partialTicks); } public static class Generator implements RoomProcessorGenerator<RoomProcessorBlazeSolver> { diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/RoomProcessorWaterPuzzle.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/RoomProcessorWaterPuzzle.java new file mode 100644 index 00000000..5cb5502a --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/RoomProcessorWaterPuzzle.java @@ -0,0 +1,96 @@ +package kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle; + +import kr.syeyoung.dungeonsguide.dungeon.data.OffsetPoint; +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.RoomProcessor; +import kr.syeyoung.dungeonsguide.roomprocessor.RoomProcessorBlazeSolver; +import kr.syeyoung.dungeonsguide.roomprocessor.RoomProcessorGenerator; +import kr.syeyoung.dungeonsguide.utils.RenderUtils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.util.BlockPos; + +import java.awt.*; + +public class RoomProcessorWaterPuzzle extends GeneralRoomProcessor { + + private boolean argumentsFulfilled = false; + + private WaterBoard waterBoard; + private OffsetPointSet doorsClosed; + private OffsetPointSet levers; + private OffsetPointSet frontBoard; + private OffsetPointSet backBoard; + private OffsetPoint water_lever; + + public RoomProcessorWaterPuzzle(DungeonRoom dungeonRoom) { + super(dungeonRoom); + frontBoard = (OffsetPointSet) dungeonRoom.getDungeonRoomInfo().getProperties().get("front"); + 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"); + + 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(); + } + } + } + + @Override + public void tick() { + super.tick(); + if (!argumentsFulfilled) return; + try { + waterBoard.tick(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void drawScreen(float partialTicks) { + super.drawScreen(partialTicks); + if (!argumentsFulfilled) return; + FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; + fr.drawString("To Open: "+waterBoard.getReqOpen(),0,200, 0xFFFFFF); + fr.drawString("Target: "+waterBoard.getTarget2(),0,200, 0xFFFFFF); + } + + @Override + public void drawWorld(float partialTicks) { + super.drawWorld(partialTicks); + if (!argumentsFulfilled) return; + BlockPos target = waterBoard.getTarget(); + if (target != null) { + RenderUtils.highlightBlock(target, new Color(0,255,255,255), partialTicks); + } + Route route = waterBoard.getCurrentRoute(); + if (route != null) { + for (WaterCondition condition : route.getConditionList()) { + SwitchData switchData = waterBoard.getValidSwitches().get(condition.getBlockId()); + if (switchData.getCurrentState() != condition.isRequiredState()) { + RenderUtils.highlightBlock(switchData.getSwitchLoc(), new Color(0,255,0,50), partialTicks); + RenderUtils.drawTextAtWorld(condition.isRequiredState() ? "on":"off",switchData.getSwitchLoc().getX(), switchData.getSwitchLoc().getY(), switchData.getSwitchLoc().getZ(), 0xFF000000,1.0f, false, false, partialTicks); + } + } + } + } + + public static class Generator implements RoomProcessorGenerator<RoomProcessorWaterPuzzle> { + @Override + public RoomProcessorWaterPuzzle createNew(DungeonRoom dungeonRoom) { + RoomProcessorWaterPuzzle defaultRoomProcessor = new RoomProcessorWaterPuzzle(dungeonRoom); + return defaultRoomProcessor; + } + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/Route.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/Route.java new file mode 100644 index 00000000..cdff0477 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/Route.java @@ -0,0 +1,25 @@ +package kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle; + +import lombok.Data; + +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; + +@Data +public class Route implements Cloneable { + private Set<WaterNode> nodes = new LinkedHashSet<WaterNode>(); + private Set<WaterCondition> conditionList = new HashSet<WaterCondition>(); + private int x, y; + + + @Override + protected Route clone() { + Route r = new Route(); + r.getNodes().addAll(nodes); + r.getConditionList().addAll(conditionList); + r.x = x; + r.y = y; + return r; + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/SwitchData.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/SwitchData.java new file mode 100644 index 00000000..79d0060b --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/SwitchData.java @@ -0,0 +1,25 @@ +package kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle; + +import kr.syeyoung.dungeonsguide.DungeonsGuide; +import kr.syeyoung.dungeonsguide.SkyblockStatus; +import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoom; +import lombok.AllArgsConstructor; +import lombok.Data; +import net.minecraft.block.BlockLever; +import net.minecraft.util.BlockPos; +import net.minecraft.world.World; + +@Data +@AllArgsConstructor +public class SwitchData { + private BlockPos switchLoc; + private BlockPos blockLoc; + + private String blockId; + + public boolean getCurrentState() { + BlockPos switch2 = getSwitchLoc(); + World w= DungeonsGuide.getDungeonsGuide().getSkyblockStatus().getContext().getWorld(); + return w.getBlockState(switch2).getValue(BlockLever.POWERED); + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/WaterBoard.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/WaterBoard.java new file mode 100644 index 00000000..f0f30f0a --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/WaterBoard.java @@ -0,0 +1,263 @@ +package kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle; + +import com.google.common.collect.Sets; +import kr.syeyoung.dungeonsguide.dungeon.data.OffsetPoint; +import kr.syeyoung.dungeonsguide.dungeon.data.OffsetPointSet; +import kr.syeyoung.dungeonsguide.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.world.World; + +import javax.vecmath.Vector2d; +import java.awt.*; +import java.util.*; +import java.util.List; + +public class WaterBoard { + WaterNode[][] board; + RoomProcessorWaterPuzzle waterPuzzle; + + private OffsetPointSet frontPlate; + private OffsetPointSet backPlate; + private OffsetPointSet levers; + private OffsetPointSet doors; + private OffsetPoint lever; + + @Getter + private List<SwitchData> switchData = new ArrayList<SwitchData>(); + @Getter + private Map<String, SwitchData> validSwitches = new HashMap<String, SwitchData>(); + + private WaterNodeStart waterNodeStart; + private Map<String, WaterNodeEnd> waterNodeEndMap = new HashMap<String, WaterNodeEnd>(); + + @Getter + private Set<String> reqOpen = new HashSet<String>(); + + @Getter + private Route currentRoute; + @Getter + private BlockPos target; + @Getter + private 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()); + + int id = Block.getIdFromBlock(w.getChunkFromBlockCoords(newPos).getBlock(newPos)); + int data = w.getChunkFromBlockCoords(newPos).getBlockMetadata(newPos); + + SwitchData sw; + switchData.add(sw = new SwitchData(pos,newPos,id+":"+data)); + validSwitches.put(id+":"+data, sw); + } + } + SwitchData sw; + switchData.add(sw = new SwitchData(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) { + WaterNodeEnd end = waterNodeEndMap.get(doorsToOpen.iterator().next()); + target = end.getBlockPos(); + target2 = end.getResultId(); + currentRoute = pathFind(end); + } + } + } + + private final Set<Point> possibleDir = Sets.newHashSet(new Point(0,-1), new Point(1,0), new Point(-1, 0)); + public Route pathFind(WaterNodeEnd endNode) { + Route start = new Route(); + start.setX(endNode.getX()); + start.setY(endNode.getY()); + start.getNodes().add(endNode); + Queue<Route> routes = new LinkedList<Route>(); + routes.add(start); + List<Route> reachedStart = new ArrayList<Route>(); + while (!routes.isEmpty()) { + Route r2 = routes.poll(); + int x = r2.getX(); + int y = r2.getY(); + int size = 0; + for (Point vec:possibleDir) { + WaterNode node = getNodeAt(x + vec.x, y + vec.y); + if (node == null) continue; + if (r2.getNodes().contains(node)) continue;; + if (!node.canWaterGoThrough()) continue; + size ++; + Route r = r2.clone(); + r.getNodes().add(node); + r.getConditionList().add(node.getCondition()); + r.setX(node.getX()); + r.setY(node.getY()); + + WaterNode void2 = getNodeAt(r.getX(), r.getY() + 1); + if ((void2 == null || void2.getCondition() == null) && !r.getNodes().contains(void2)) { + continue; + } + + if (checkContradiction(r.getConditionList())) { + continue; + } + + if (node instanceof WaterNodeStart) { + reachedStart.add(r); + } else { + routes.add(r); + } + } + } + Iterator<Route> routeIter = reachedStart.iterator(); + while (routeIter.hasNext()) { + Route route = routeIter.next(); + + addRouteConditions(route); + if (checkContradiction(route.getConditionList())) + routeIter.remove(); + } + + return reachedStart.get(0); + } + + public void addRouteConditions(Route r) { + int prevY = 0; + int startX = -1; + for (WaterNode node : r.getNodes()) { + int currY = node.getY(); + if (currY != prevY) { + if (startX != -1) { + int offset = node.getX() - startX; + if (offset != 0) { + int start = startX + (offset > 0 ? 1 : -1); + int end = node.getX() + offset; + int y = node.getY() + 2; + int y2 = node.getY() + 1; + + for (int x = start; (start < end) ? (x <= end) : (x >= end); x += (start < end) ?1:-1){ + WaterNode node2 = getNodeAt(x, y2); + if (node2 == null || !node2.canWaterGoThrough()) break; + node2 = getNodeAt(x, y); + if (node2 == null || node2.getCondition() == null) { + r.getConditionList().add(new WaterConditionContradict()); + return; + } else { + r.getConditionList().add(node2.getCondition().invert()); + } + } + } + } + startX = node.getX(); + } + } + } + + 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[19][25]; + 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) && frontId == 0) { + String resId = backId + ":"+backData; + node = new WaterNodeToggleable(resId, isSwitchActive(validSwitches.get(resId)), front.getBlockPos(waterPuzzle.getDungeonRoom()),x,y); + } else if (validSwitches.containsKey(frontId +":"+frontData)) { + String resId = frontId +":"+frontData; + node = new WaterNodeToggleable(resId, !isSwitchActive(validSwitches.get(resId)), front.getBlockPos(waterPuzzle.getDungeonRoom()),x,y); + } else if (frontId == 0) { + 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 == 0) { + waterNodeStart = (WaterNodeStart) (node = new WaterNodeStart(front.getBlockPos(waterPuzzle.getDungeonRoom()),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; + } + } + } + + // true if contradiction + private boolean checkContradiction(Set<WaterCondition> conditions) { + Map<String, Boolean> conditionMap = new HashMap<String, Boolean>(); + for (WaterCondition condition : conditions) { + if (condition instanceof WaterConditionContradict) return true; + if (conditionMap.containsKey(condition.getBlockId())) { + if (conditionMap.get(condition.getBlockId()) != condition.isRequiredState()) + return true; + } else { + conditionMap.put(condition.getBlockId(), condition.isRequiredState()); + } + } + return false; + } + + private boolean isSwitchActive(SwitchData switchData) { + BlockPos switch2 = switchData.getSwitchLoc(); + World w= waterPuzzle.getDungeonRoom().getContext().getWorld(); + boolean bool = w.getBlockState(switch2).getValue(BlockLever.POWERED); + return bool; + } + + +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/WaterCondition.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/WaterCondition.java new file mode 100644 index 00000000..26678af3 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/WaterCondition.java @@ -0,0 +1,15 @@ +package kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class WaterCondition { + private String blockId; + private boolean requiredState; + + public WaterCondition invert() { + return new WaterCondition(blockId, !requiredState); + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/WaterConditionContradict.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/WaterConditionContradict.java new file mode 100644 index 00000000..64339655 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/WaterConditionContradict.java @@ -0,0 +1,7 @@ +package kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle; + +public class WaterConditionContradict extends WaterCondition { + public WaterConditionContradict() { + super("contradict", true); + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/WaterNode.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/WaterNode.java new file mode 100644 index 00000000..efd872bc --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/WaterNode.java @@ -0,0 +1,18 @@ +package kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle; + +import net.minecraft.util.BlockPos; +import net.minecraft.world.World; + +public interface WaterNode { + boolean canWaterGoThrough(); + + // condition for water go + WaterCondition getCondition(); + + boolean isWaterFilled(World w); + + BlockPos getBlockPos(); + + int getX(); + int getY(); +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeAir.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeAir.java new file mode 100644 index 00000000..d22fde2e --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeAir.java @@ -0,0 +1,37 @@ +package kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle.nodes; + +import kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle.WaterCondition; +import kr.syeyoung.dungeonsguide.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 WaterCondition 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; +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeEnd.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeEnd.java new file mode 100644 index 00000000..1cc079e2 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeEnd.java @@ -0,0 +1,38 @@ +package kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle.nodes; + +import kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle.WaterCondition; +import kr.syeyoung.dungeonsguide.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 WaterCondition 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; +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeStart.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeStart.java new file mode 100644 index 00000000..11661fcc --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeStart.java @@ -0,0 +1,39 @@ +package kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle.nodes; + +import kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle.WaterCondition; +import kr.syeyoung.dungeonsguide.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 { + + BlockPos blockPos; + + @Override + public boolean canWaterGoThrough() { + return true; + } + + @Override + public WaterCondition getCondition() { + return new WaterCondition("mainStream", true); + } + + @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; +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeToggleable.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeToggleable.java new file mode 100644 index 00000000..cc714129 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeToggleable.java @@ -0,0 +1,42 @@ +package kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle.nodes; + +import kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle.WaterCondition; +import kr.syeyoung.dungeonsguide.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 WaterCondition getCondition() { + return new WaterCondition(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 BlockPos getBlockPos() { + return blockPos; + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeWall.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeWall.java new file mode 100644 index 00000000..18260adf --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/waterpuzzle/nodes/WaterNodeWall.java @@ -0,0 +1,39 @@ +package kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle.nodes; + +import kr.syeyoung.dungeonsguide.roomprocessor.waterpuzzle.WaterCondition; +import kr.syeyoung.dungeonsguide.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 WaterCondition 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; + } +} |