v2.3.0: further improvements to rot garden layouts in rare cases

This commit is contained in:
Evan Debenham
2024-01-07 14:49:54 -05:00
parent 71856bee8c
commit cb98b88637

View File

@@ -47,13 +47,7 @@ public class RotGardenRoom extends SpecialRoom {
@Override @Override
public int minHeight() { return 10; } public int minHeight() { return 10; }
@Override public void paint( Level level ) {
public boolean canConnect(Point p) {
//refuses connections next to corners, this helps ensure better terrain layouts
return super.canConnect(p) && ((p.x > left+1 && p.x < right-1) || (p.y > top+1 && p.y < bottom-1));
}
public void paint(Level level ) {
Door entrance = entrance(); Door entrance = entrance();
entrance.set(Door.Type.LOCKED); entrance.set(Door.Type.LOCKED);
@@ -62,50 +56,55 @@ public class RotGardenRoom extends SpecialRoom {
//define basic terrain, mostly high grass with some chaotically placed wall tiles //define basic terrain, mostly high grass with some chaotically placed wall tiles
Painter.fill(level, this, Terrain.WALL); Painter.fill(level, this, Terrain.WALL);
Painter.set(level, entrance, Terrain.LOCKED_DOOR); Painter.set(level, entrance, Terrain.LOCKED_DOOR);
Painter.fill(level, this, 1, Terrain.HIGH_GRASS);
for (int i = 0; i < 12; i ++){
Painter.set(level, random(1), Terrain.WALL);
}
for (int i = 0; i < 8; i ++){
Painter.set(level, random(2), Terrain.WALL);
}
for (int i = 0; i < 4; i ++){
Painter.set(level, random(3), Terrain.WALL);
}
Painter.drawInside(level, this, entrance, 3, Terrain.HIGH_GRASS);
boolean[] passable = new boolean[level.length()];
for (int i = 0; i < passable.length; i++){
passable[i] = level.map[i] != Terrain.WALL;
}
//place the heart in a slightly random location sufficiently far from the entrance
int entryPos = level.pointToCell(entrance());
PathFinder.buildDistanceMap(entryPos, passable);
ArrayList<Integer> candidates = new ArrayList<>(); ArrayList<Integer> candidates = new ArrayList<>();
for (Point p : getPoints()){ boolean[] passable = new boolean[level.length()];
int i = level.pointToCell(p); int entryPos = level.pointToCell(entrance());
if (PathFinder.distance[i] != Integer.MAX_VALUE){ do {
if (PathFinder.distance[i] >= 3){ Painter.fill(level, this, 1, Terrain.HIGH_GRASS);
candidates.add(i); for (int i = 0; i < 12; i++) {
} Painter.set(level, random(1), Terrain.WALL);
} else { }
//fill in grass tiles that are enclosed for (int i = 0; i < 8; i++) {
if (level.map[i] == Terrain.HIGH_GRASS){ Painter.set(level, random(2), Terrain.WALL);
level.map[i] = Terrain.WALL; }
for (int i = 0; i < 4; i++) {
Painter.set(level, random(3), Terrain.WALL);
}
Painter.drawInside(level, this, entrance, 3, Terrain.HIGH_GRASS);
for (int i = 0; i < passable.length; i++) {
passable[i] = level.map[i] != Terrain.WALL;
}
//place the heart in a slightly random location sufficiently far from the entrance
PathFinder.buildDistanceMap(entryPos, passable);
candidates.clear();
for (Point p : getPoints()) {
int i = level.pointToCell(p);
if (PathFinder.distance[i] != Integer.MAX_VALUE) {
if (PathFinder.distance[i] >= 7) {
candidates.add(i);
}
} else {
//fill in grass tiles that are enclosed
if (level.map[i] == Terrain.HIGH_GRASS) {
level.map[i] = Terrain.WALL;
}
} }
} }
} Random.shuffle(candidates);
Random.shuffle(candidates); int closestPos = 7;
int closestPos = 3; while (candidates.size() > 5) {
while (candidates.size() > 5){ for (Integer i : candidates.toArray(new Integer[0])) {
for (Integer i : candidates.toArray(new Integer[0])){ if (candidates.size() > 5 && PathFinder.distance[i] == closestPos) {
if (candidates.size() > 5 && PathFinder.distance[i] == closestPos){ candidates.remove(i);
candidates.remove(i); }
} }
closestPos++;
} }
closestPos++;
} } while (candidates.isEmpty());
int heartPos = Random.element(candidates); int heartPos = Random.element(candidates);
placePlant(level, heartPos, new RotHeart()); placePlant(level, heartPos, new RotHeart());