From 9a902d97bdc39736012546270d69202d89f9c968 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Tue, 11 Apr 2017 17:35:05 -0400 Subject: [PATCH] v0.6.0: added connection limit logic for rooms --- .../levels/builders/LineBuilder.java | 66 ++++++------- .../levels/rooms/Room.java | 99 +++++++++++++++---- .../levels/rooms/special/BlacksmithRoom.java | 2 +- .../levels/rooms/special/RatKingRoom.java | 2 +- .../levels/rooms/special/SpecialRoom.java | 11 +++ .../levels/rooms/standard/EntranceRoom.java | 2 +- .../levels/rooms/standard/ExitRoom.java | 2 +- .../levels/rooms/standard/StandardRoom.java | 12 +++ .../levels/rooms/tunnel/TunnelRoom.java | 12 +++ 9 files changed, 149 insertions(+), 59 deletions(-) diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LineBuilder.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LineBuilder.java index 5e7270530..d466b5735 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LineBuilder.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LineBuilder.java @@ -23,10 +23,8 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.builders; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.ShopRoom; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.EntranceRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.ExitRoom; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.tunnel.TunnelRoom; import com.watabou.utils.Point; import com.watabou.utils.Random; @@ -42,8 +40,9 @@ public class LineBuilder extends Builder { Room entrance = null; Room exit = null; Room shop = null; - ArrayList standards = new ArrayList<>(); - ArrayList specials = new ArrayList<>(); + + ArrayList multiConnections = new ArrayList<>(); + ArrayList singleConnections = new ArrayList<>(); for (Room r : rooms){ if (r instanceof EntranceRoom){ @@ -52,10 +51,10 @@ public class LineBuilder extends Builder { exit = r; } else if (r instanceof ShopRoom){ shop = r; - } else if (r instanceof StandardRoom){ - standards.add((StandardRoom)r); - } else if (r instanceof SpecialRoom){ - specials.add((SpecialRoom)r); + } else if (r.maxConnections(Room.ALL) > 1){ + multiConnections.add(r); + } else if (r.maxConnections(Room.ALL) == 1){ + singleConnections.add(r); } } @@ -71,19 +70,17 @@ public class LineBuilder extends Builder { if (shop != null){ shop.setSize(); - shop.setPos(-shop.width(), -shop.height()/2); + shop.setPos(-shop.width()+1, -shop.height()/2); shop.connect(entrance); } - int standardsOnPath = standards.size()/5 + Random.Int(2); - standardsOnPath = Math.min(standardsOnPath, standards.size()); - - //standardsOnPath = standards.size(); + int roomsOnPath = multiConnections.size()/5 + Random.Int(2); + roomsOnPath = Math.min(roomsOnPath, multiConnections.size()); Room curr = entrance; - for (int i = 0; i < standardsOnPath; i++){ - if (Random.Int(3) == 0){ + for (int i = 0; i <= roomsOnPath; i++){ + if (Random.Int(2) == 0){ TunnelRoom t = new TunnelRoom(); t.setSize(); t.setPos( curr.right, -t.height()/2); @@ -92,7 +89,7 @@ public class LineBuilder extends Builder { branchable.add(t); curr = t; } - if (Random.Int(3) == 0){ + if (Random.Int(2) == 0){ TunnelRoom t = new TunnelRoom(); t.setSize(); t.setPos( curr.right, -t.height()/2); @@ -101,27 +98,26 @@ public class LineBuilder extends Builder { branchable.add(t); curr = t; } - StandardRoom s = standards.get(i); - s.setSize(); - s.setPos( curr.right, -s.height()/2); - s.connect(curr); - branchable.add(s); - curr = s; + Room r = (i == roomsOnPath ? exit : multiConnections.get(i)); + r.setSize(); + r.setPos( curr.right, -r.height()/2); + r.connect(curr); + branchable.add(r); + curr = r; } - //place exit - exit.setSize(); - exit.setPos( curr.right, -exit.height()/2); - exit.connect(curr); - branchable.add(exit); ArrayList upBrancheable = new ArrayList<>(branchable); ArrayList downBrancheable = new ArrayList<>(branchable); //place branches - int i = standardsOnPath; - while (i < standards.size() + specials.size()){ - boolean up = !upBrancheable.isEmpty() && (Random.Int(2) == 0 || downBrancheable.isEmpty()); + int i = roomsOnPath; + while (i < multiConnections.size() + singleConnections.size()){ + if (upBrancheable.isEmpty() && downBrancheable.isEmpty()) + return null; + + boolean up = downBrancheable.isEmpty() + || (Random.Int(2) == 0 && !upBrancheable.isEmpty()); if (up){ curr = Random.element(upBrancheable); @@ -131,7 +127,7 @@ public class LineBuilder extends Builder { downBrancheable.remove(curr); } - if (Random.Int(2) == 0){ + if (Random.Int(3) == 0){ TunnelRoom t = new TunnelRoom(); if (placeBranchRoom(up, curr, t, rooms)){ rooms.add(t); @@ -150,16 +146,16 @@ public class LineBuilder extends Builder { curr = t; } Room r; - if (i < standards.size()) { - r = standards.get(i); + if (i < multiConnections.size()) { + r = multiConnections.get(i); } else { - r = specials.get(i - standards.size()); + r = singleConnections.get(i - multiConnections.size()); } if (!placeBranchRoom(up, curr, r, rooms)){ continue; } - if (r instanceof StandardRoom && Random.Int(3) == 0) { + if (r.canConnect(up ? Room.TOP : Room.BOTTOM) && Random.Int(3) == 0) { if (up) upBrancheable.add(r); else downBrancheable.add(r); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/Room.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/Room.java index 4a1b6c271..1092c26ec 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/Room.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/Room.java @@ -68,7 +68,13 @@ public class Room extends Rect implements Graph.Node, Bundlable { return this; } - //Note: when overriding these it is STRONGLY ADVISED to store any randomly decided values. + //TODO make abstract + public void paint(Level level){ } + + + // **** Spatial logic **** + + //Note: when overriding these YOU MUST store any randomly decided values. //With the same room and the same parameters these should always return //the same value over multiple calls, even if there's some randomness initially. public int minWidth(){ @@ -128,15 +134,78 @@ public class Room extends Rect implements Graph.Node, Bundlable { return super.height()+1; } - public void paint(Level level){ } - public Point random() { - return random( 0 ); + return random( 1 ); } public Point random( int m ) { - return new Point( Random.Int( left + 1 + m, right - m ), - Random.Int( top + 1 + m, bottom - m )); + return new Point( Random.Int( left + m, right - m ), + Random.Int( top + m, bottom - m )); + } + + public boolean inside( Point p ) { + return p.x > left && p.y > top && p.x < right && p.y < bottom; + } + + public Point center() { + return new Point( + (left + right) / 2 + (((right - left) % 2) == 1 ? Random.Int( 2 ) : 0), + (top + bottom) / 2 + (((bottom - top) % 2) == 1 ? Random.Int( 2 ) : 0) ); + } + + + // **** Connection logic **** + + public static final int ALL = 0; + public static final int LEFT = 1; + public static final int TOP = 2; + public static final int RIGHT = 3; + public static final int BOTTOM = 4; + + //TODO make abstract + public int minConnections(int direction){ return -1; } + + public int curConnections(int direction){ + if (direction == ALL) { + return connected.size(); + + } else { + int total = 0; + for (Room r : connected.keySet()){ + Rect i = intersect( r ); + if (direction == LEFT && i.width() == 0 && i.left == left) total++; + else if (direction == TOP && i.height() == 0 && i.top == top) total++; + else if (direction == RIGHT && i.width() == 0 && i.right == right) total++; + else if (direction == BOTTOM && i.height() == 0 && i.bottom == bottom) total++; + } + return total; + } + } + + public int remConnections(int direction){ + if (curConnections(ALL) >= maxConnections(ALL)) return 0; + else return maxConnections(direction) - curConnections(direction); + } + + //TODO make abstract + public int maxConnections(int direction){ return -1; } + + public boolean canConnect(int direction){ + return remConnections(direction) > 0; + } + + public boolean canConnect( Room r ){ + Rect i = intersect( r ); + if (i.width() == 0 && i.left == left) + return canConnect(LEFT); + else if (i.height() == 0 && i.top == top) + return canConnect(TOP); + else if (i.width() == 0 && i.right == right) + return canConnect(RIGHT); + else if (i.height() == 0 && i.bottom == bottom) + return canConnect(BOTTOM); + else + return false; } public boolean addNeigbour( Room other ) { @@ -154,23 +223,13 @@ public class Room extends Rect implements Graph.Node, Bundlable { } public boolean connect( Room room ) { - if (!neigbours.contains(room) && !addNeigbour(room)) - return false; - if (!connected.containsKey( room )) { + if ((neigbours.contains(room) || addNeigbour(room)) + && !connected.containsKey( room ) && canConnect(room) && room.canConnect(this)) { connected.put( room, null ); room.connected.put( this, null ); + return true; } - return true; - } - - public boolean inside( Point p ) { - return p.x > left && p.y > top && p.x < right && p.y < bottom; - } - - public Point center() { - return new Point( - (left + right) / 2 + (((right - left) % 2) == 1 ? Random.Int( 2 ) : 0), - (top + bottom) / 2 + (((bottom - top) % 2) == 1 ? Random.Int( 2 ) : 0) ); + return false; } // **** Graph.Node interface **** diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/BlacksmithRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/BlacksmithRoom.java index 2713e1a55..848c62c9e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/BlacksmithRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/BlacksmithRoom.java @@ -57,7 +57,7 @@ public class BlacksmithRoom extends SpecialRoom { Blacksmith npc = new Blacksmith(); do { - npc.pos = level.pointToCell(random( 1 )); + npc.pos = level.pointToCell(random( 2 )); } while (level.heaps.get( npc.pos ) != null); level.mobs.add( npc ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/RatKingRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/RatKingRoom.java index 4e0c054ee..d05a4bd2a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/RatKingRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/RatKingRoom.java @@ -52,7 +52,7 @@ public class RatKingRoom extends SpecialRoom { } RatKing king = new RatKing(); - king.pos = level.pointToCell(random( 1 )); + king.pos = level.pointToCell(random( 2 )); level.mobs.add( king ); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/SpecialRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/SpecialRoom.java index bef6e8e87..ce902430d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/SpecialRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/SpecialRoom.java @@ -40,6 +40,17 @@ public class SpecialRoom extends Room { } public int maxHeight() { return 10; } + @Override + public int minConnections(int direction) { + if (direction == ALL) return 1; + else return 0; + } + + @Override + public int maxConnections(int direction) { + return 1; + } + public Door entrance() { return connected.values().iterator().next(); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/EntranceRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/EntranceRoom.java index b04f0383d..3065b7d07 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/EntranceRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/EntranceRoom.java @@ -48,7 +48,7 @@ public class EntranceRoom extends StandardRoom { } do { - level.entrance = level.pointToCell(random(1)); + level.entrance = level.pointToCell(random(2)); } while (level.findMob(level.entrance) != null); Painter.set( level, level.entrance, Terrain.ENTRANCE ); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/ExitRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/ExitRoom.java index 763fac94a..000fb1811 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/ExitRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/ExitRoom.java @@ -47,7 +47,7 @@ public class ExitRoom extends StandardRoom { door.set( Room.Door.Type.REGULAR ); } - level.exit = level.pointToCell(random( 1 )); + level.exit = level.pointToCell(random( 2 )); Painter.set( level, level.exit, Terrain.EXIT ); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/StandardRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/StandardRoom.java index 9ea7574d6..181a88005 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/StandardRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/StandardRoom.java @@ -54,6 +54,18 @@ public abstract class StandardRoom extends Room { public int minHeight() { return sizeCat.minDim; } public int maxHeight() { return sizeCat.maxDim; } + @Override + public int minConnections(int direction) { + if (direction == ALL) return 1; + else return 0; + } + + @Override + public int maxConnections(int direction) { + if (direction == ALL) return 16; + else return 4; + } + private static HashMap, Float> chances = new HashMap<>(); static { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/tunnel/TunnelRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/tunnel/TunnelRoom.java index d644eb598..727a6279a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/tunnel/TunnelRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/tunnel/TunnelRoom.java @@ -37,6 +37,18 @@ public class TunnelRoom extends Room { public int minHeight() { return 3; } public int maxHeight() { return 10; } + @Override + public int minConnections(int direction) { + if (direction == ALL) return 2; + else return 0; + } + + @Override + public int maxConnections(int direction) { + if (direction == ALL) return 16; + else return 4; + } + public void paint(Level level) { int floor = level.tunnelTile();