v0.6.1: improved sewer pipe rooms when they have many connections

This commit is contained in:
Evan Debenham 2017-08-01 16:45:37 -04:00
parent 8dc88b2565
commit f500ba87ec

View File

@ -31,6 +31,8 @@ import com.watabou.utils.PointF;
import com.watabou.utils.Random;
import com.watabou.utils.Rect;
import java.util.ArrayList;
public class SewerPipeRoom extends StandardRoom {
@Override
@ -54,7 +56,7 @@ public class SewerPipeRoom extends StandardRoom {
return super.canConnect(p) && ((p.x > left+1 && p.x < right-1) || (p.y > top+1 && p.y < bottom-1));
}
//FIXME lots of copy-pasta from tunnel rooms here
//FIXME this class is a total mess, lots of copy-pasta from tunnel and perimeter rooms here
@Override
public void paint(Level level) {
@ -62,6 +64,7 @@ public class SewerPipeRoom extends StandardRoom {
Rect c = getConnectionSpace();
if (connected.size() <= 3) {
for (Door door : connected.values()) {
Point start;
@ -100,6 +103,44 @@ public class SewerPipeRoom extends StandardRoom {
Painter.drawLine(level, mid, end, Terrain.WATER);
}
} else {
ArrayList<Point> pointsToFill = new ArrayList<>();
for (Point door : connected.values()) {
Point p = new Point(door);
if (p.y == top){
p.y+=2;
} else if (p.y == bottom) {
p.y-=2;
} else if (p.x == left){
p.x+=2;
} else {
p.x-=2;
}
pointsToFill.add( p );
}
ArrayList<Point> pointsFilled = new ArrayList<>();
pointsFilled.add(pointsToFill.remove(0));
Point from = null, to = null;
int shortestDistance;
while(!pointsToFill.isEmpty()){
shortestDistance = Integer.MAX_VALUE;
for (Point f : pointsFilled){
for (Point t : pointsToFill){
int dist = distanceBetweenPoints(f, t);
if (dist < shortestDistance){
from = f;
to = t;
shortestDistance = dist;
}
}
}
fillBetweenPoints(level, from, to, Terrain.WATER);
pointsFilled.add(to);
pointsToFill.remove(to);
}
}
for(Point p : getPoints()){
int cell = level.pointToCell(p);
@ -148,4 +189,86 @@ public class SewerPipeRoom extends StandardRoom {
return c;
}
private int spaceBetween(int a, int b){
return Math.abs(a - b)-1;
}
//gets the path distance between two points
private int distanceBetweenPoints(Point a, Point b){
//on the same side
if (a.y == b.y || a.x == b.x){
return Math.max(spaceBetween(a.x, b.x), spaceBetween(a.y, b.y));
}
//otherwise...
//subtract 1 at the end to account for overlap
return
Math.min(spaceBetween(left, a.x) + spaceBetween(left, b.x),
spaceBetween(right, a.x) + spaceBetween(right, b.x))
+
Math.min(spaceBetween(top, a.y) + spaceBetween(top, b.y),
spaceBetween(bottom, a.y) + spaceBetween(bottom, b.y))
-
1;
}
private Point[] corners;
//picks the smallest path to fill between two points
private void fillBetweenPoints(Level level, Point from, Point to, int floor){
//doors are along the same side
if (from.y == to.y || from.x == to.x){
Painter.fill(level,
Math.min(from.x, to.x),
Math.min(from.y, to.y),
spaceBetween(from.x, to.x) + 2,
spaceBetween(from.y, to.y) + 2,
floor);
return;
}
//set up corners
if (corners == null){
corners = new Point[4];
corners[0] = new Point(left+2, top+2);
corners[1] = new Point(right-2, top+2);
corners[2] = new Point(right-2, bottom-2);
corners[3] = new Point(left+2, bottom-2);
}
//doors on adjacent sides
for (Point c : corners){
if ((c.x == from.x || c.y == from.y) && (c.x == to.x || c.y == to.y)){
Painter.drawLine(level, from, c, floor);
Painter.drawLine(level, c, to, floor);
return;
}
}
//doors on opposite sides
Point side;
if (from.y == top+1 || from.y == bottom-1){
//connect along the left, or right side
if (spaceBetween(left, from.x) + spaceBetween(left, to.x) <=
spaceBetween(right, from.x) + spaceBetween(right, to.x)){
side = new Point(left+1, top + height()/2);
} else {
side = new Point(right-1, top + height()/2);
}
} else {
//connect along the top, or bottom side
if (spaceBetween(top, from.y) + spaceBetween(top, to.y) <=
spaceBetween(bottom, from.y) + spaceBetween(bottom, to.y)){
side = new Point(left + width()/2, top+1);
} else {
side = new Point(left + width()/2, bottom-1);
}
}
//treat this as two connections with adjacent sides
fillBetweenPoints(level, from, side, floor);
fillBetweenPoints(level, side, to, floor);
}
}