v0.6.1: improved sewer pipe rooms when they have many connections
This commit is contained in:
parent
8dc88b2565
commit
f500ba87ec
|
@ -31,6 +31,8 @@ import com.watabou.utils.PointF;
|
||||||
import com.watabou.utils.Random;
|
import com.watabou.utils.Random;
|
||||||
import com.watabou.utils.Rect;
|
import com.watabou.utils.Rect;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class SewerPipeRoom extends StandardRoom {
|
public class SewerPipeRoom extends StandardRoom {
|
||||||
|
|
||||||
@Override
|
@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));
|
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
|
@Override
|
||||||
public void paint(Level level) {
|
public void paint(Level level) {
|
||||||
|
|
||||||
|
@ -62,43 +64,82 @@ public class SewerPipeRoom extends StandardRoom {
|
||||||
|
|
||||||
Rect c = getConnectionSpace();
|
Rect c = getConnectionSpace();
|
||||||
|
|
||||||
for (Door door : connected.values()) {
|
if (connected.size() <= 3) {
|
||||||
|
for (Door door : connected.values()) {
|
||||||
Point start;
|
|
||||||
Point mid;
|
Point start;
|
||||||
Point end;
|
Point mid;
|
||||||
|
Point end;
|
||||||
start = new Point(door);
|
|
||||||
if (start.x == left) start.x+=2;
|
start = new Point(door);
|
||||||
else if (start.y == top) start.y+=2;
|
if (start.x == left) start.x += 2;
|
||||||
else if (start.x == right) start.x-=2;
|
else if (start.y == top) start.y += 2;
|
||||||
else if (start.y == bottom) start.y-=2;
|
else if (start.x == right) start.x -= 2;
|
||||||
|
else if (start.y == bottom) start.y -= 2;
|
||||||
int rightShift;
|
|
||||||
int downShift;
|
int rightShift;
|
||||||
|
int downShift;
|
||||||
if (start.x < c.left) rightShift = c.left - start.x;
|
|
||||||
else if (start.x > c.right) rightShift = c.right - start.x;
|
if (start.x < c.left) rightShift = c.left - start.x;
|
||||||
else rightShift = 0;
|
else if (start.x > c.right) rightShift = c.right - start.x;
|
||||||
|
else rightShift = 0;
|
||||||
if (start.y < c.top) downShift = c.top - start.y;
|
|
||||||
else if (start.y > c.bottom) downShift = c.bottom - start.y;
|
if (start.y < c.top) downShift = c.top - start.y;
|
||||||
else downShift = 0;
|
else if (start.y > c.bottom) downShift = c.bottom - start.y;
|
||||||
|
else downShift = 0;
|
||||||
//always goes inward first
|
|
||||||
if (door.x == left || door.x == right){
|
//always goes inward first
|
||||||
mid = new Point(start.x + rightShift, start.y);
|
if (door.x == left || door.x == right) {
|
||||||
end = new Point(mid.x, mid.y + downShift);
|
mid = new Point(start.x + rightShift, start.y);
|
||||||
|
end = new Point(mid.x, mid.y + downShift);
|
||||||
} else {
|
|
||||||
mid = new Point(start.x, start.y + downShift);
|
} else {
|
||||||
end = new Point(mid.x + rightShift, mid.y);
|
mid = new Point(start.x, start.y + downShift);
|
||||||
|
end = new Point(mid.x + rightShift, mid.y);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Painter.drawLine(level, start, mid, Terrain.WATER);
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
Painter.drawLine( level, start, mid, Terrain.WATER);
|
|
||||||
Painter.drawLine( level, mid, end, Terrain.WATER );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Point p : getPoints()){
|
for(Point p : getPoints()){
|
||||||
|
@ -147,5 +188,87 @@ public class SewerPipeRoom extends StandardRoom {
|
||||||
|
|
||||||
return c;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user