v0.6.0: refactoring, bugfixes, and improvements to builder logic

This commit is contained in:
Evan Debenham
2017-05-28 14:06:40 -04:00
parent a217508571
commit 0ff9af6522
3 changed files with 76 additions and 56 deletions
@@ -68,61 +68,67 @@ public abstract class Builder {
} }
} }
//iterate through all rooms we are overlapping, and find which one would take //iterate through all rooms we are overlapping, and find the closest one
//the largest area reduction to resolve the overlapping Room closestRoom = null;
Room biggestCollision = null; int closestDiff = Integer.MAX_VALUE;
int wDiff, hDiff, biggestDiff = 0; boolean inside = true;
boolean widthCollision = false; int curDiff = 0;
for (Room room : colliding){ for (Room curRoom : colliding){
if (start.x <= curRoom.left){
inside = false;
curDiff += curRoom.left - start.x;
} else if (start.x >= curRoom.right){
inside = false;
curDiff += start.x - curRoom.right;
}
if (start.y <= curRoom.top){
inside = false;
curDiff += curRoom.top - start.y;
} else if (start.y >= curRoom.bottom){
inside = false;
curDiff += start.y - curRoom.bottom;
}
if (inside){
space.set(start.x, start.y, start.x, start.y);
return space;
}
if (curDiff < closestDiff){
closestDiff = curDiff;
closestRoom = curRoom;
}
}
int wDiff, hDiff;
if (closestRoom != null){
wDiff = Integer.MAX_VALUE; wDiff = Integer.MAX_VALUE;
if (room.left >= start.x){ if (closestRoom.left >= start.x){
wDiff = (space.right - room.left) * (space.height() + 1); wDiff = (space.right - closestRoom.left) * (space.height() + 1);
} else if (room.right <= start.x){ } else if (closestRoom.right <= start.x){
wDiff = (room.right - space.left) * (space.height() + 1); wDiff = (closestRoom.right - space.left) * (space.height() + 1);
} }
hDiff = Integer.MAX_VALUE; hDiff = Integer.MAX_VALUE;
if (room.top >= start.y){ if (closestRoom.top >= start.y){
hDiff = (space.bottom - room.top) * (space.width() + 1); hDiff = (space.bottom - closestRoom.top) * (space.width() + 1);
} else if (room.bottom <= start.y){ } else if (closestRoom.bottom <= start.y){
hDiff = (room.bottom - space.top) * (space.width() + 1); hDiff = (closestRoom.bottom - space.top) * (space.width() + 1);
} }
//our start is inside this room, return an empty rect //reduce by as little as possible to resolve the collision
if (hDiff == Integer.MAX_VALUE && wDiff == Integer.MAX_VALUE){ if (wDiff < hDiff || wDiff == hDiff && Random.Int(2) == 0){
space.set(0, 0, 0, 0); if (closestRoom.left >= start.x && closestRoom.left < space.right) space.right = closestRoom.left;
return space; if (closestRoom.right <= start.x && closestRoom.right > space.left) space.left = closestRoom.right;
} else { } else {
if (wDiff < hDiff || (wDiff == hDiff && Random.Int(2) == 0)){ if (closestRoom.top >= start.y && closestRoom.top < space.bottom) space.bottom = closestRoom.top;
if (wDiff >= biggestDiff){ if (closestRoom.bottom <= start.y && closestRoom.bottom > space.top) space.top = closestRoom.bottom;
biggestDiff = wDiff;
biggestCollision = room;
widthCollision = true;
}
} else {
if (hDiff >= biggestDiff){
biggestDiff = hDiff;
biggestCollision = room;
widthCollision = false;
}
}
} }
colliding.remove(closestRoom);
}
//reduce the available space in order to not overlap with the biggest collision we found
if (biggestCollision != null){
if (widthCollision){
if (biggestCollision.left >= start.x && biggestCollision.left < space.right) space.right = biggestCollision.left;
if (biggestCollision.right <= start.x && biggestCollision.right > space.left) space.left = biggestCollision.right;
} else {
if (biggestCollision.top >= start.y && biggestCollision.top < space.bottom) space.bottom = biggestCollision.top;
if (biggestCollision.bottom <= start.y && biggestCollision.bottom > space.top) space.top = biggestCollision.bottom;
}
colliding.remove(biggestCollision);
} else { } else {
colliding.clear(); colliding.clear();
} }
@@ -140,7 +146,10 @@ public abstract class Builder {
PointF fromCenter = new PointF((from.left + from.right)/2f, (from.top + from.bottom)/2f); PointF fromCenter = new PointF((from.left + from.right)/2f, (from.top + from.bottom)/2f);
PointF toCenter = new PointF((to.left + to.right)/2f, (to.top + to.bottom)/2f); PointF toCenter = new PointF((to.left + to.right)/2f, (to.top + to.bottom)/2f);
double m = (toCenter.y - fromCenter.y)/(toCenter.x - fromCenter.x); double m = (toCenter.y - fromCenter.y)/(toCenter.x - fromCenter.x);
return (float)(A*(Math.atan(m) + Math.PI/2f));
float angle = (float)(A*(Math.atan(m) + Math.PI/2.0));
if (fromCenter.x > toCenter.x) angle -= 180f;
return angle;
} }
//Attempts to place a room such that the angle between the center of the previous room //Attempts to place a room such that the angle between the center of the previous room
@@ -97,7 +97,7 @@ public class LoopBuilder extends RegularBuilder {
} }
} }
if (exit != null) loop.add(loop.size()/2, exit); if (exit != null) loop.add((loop.size()+1)/2, exit);
Room prev = entrance; Room prev = entrance;
float targetAngle; float targetAngle;
@@ -114,16 +114,27 @@ public class LoopBuilder extends RegularBuilder {
} }
} }
//FIXME this is lazy, there are ways to do this without relying on chance //FIXME this is still fairly chance reliant
if (!prev.connect(entrance)){ // should just write a general function for stitching two rooms together in builder
return null; while (!prev.connect(entrance)){
ConnectionRoom c = ConnectionRoom.createRoom();
if (placeRoom(loop, prev, c, angleBetweenRooms(prev, entrance)) == -1){
return null;
}
loop.add(c);
rooms.add(c);
prev = c;
} }
if (shop != null) { if (shop != null) {
float angle; float angle;
int tries = 10;
do { do {
angle = placeRoom(loop, entrance, shop, Random.Float(360f)); angle = placeRoom(loop, entrance, shop, Random.Float(360f));
} while (angle == -1); tries--;
} while (angle == -1 && tries >= 0);
if (angle == -1) return null;
} }
ArrayList<Room> branchable = new ArrayList<>(loop); ArrayList<Room> branchable = new ArrayList<>(loop);
@@ -56,8 +56,8 @@ public abstract class RegularBuilder extends Builder {
return this; return this;
} }
protected float[] pathTunnelChances = new float[]{2, 3, 1}; protected float[] pathTunnelChances = new float[]{2, 6, 2};
protected float[] branchTunnelChances = new float[]{3, 2, 1}; protected float[] branchTunnelChances = new float[]{5, 4, 1};
public RegularBuilder setTunnelLength( float[] path, float[] branch){ public RegularBuilder setTunnelLength( float[] path, float[] branch){
pathTunnelChances = path; pathTunnelChances = path;
@@ -173,7 +173,7 @@ public abstract class RegularBuilder extends Builder {
continue; continue;
} }
branchable.addAll(connectingRoomsThisBranch); if (Random.Float() < 0.33f) branchable.addAll(connectingRoomsThisBranch);
if (r.maxConnections(Room.ALL) > 1) { if (r.maxConnections(Room.ALL) > 1) {
if (r instanceof StandardRoom){ if (r instanceof StandardRoom){
for (int j = 0; j < ((StandardRoom) r).sizeCat.connectionWeight(); j++){ for (int j = 0; j < ((StandardRoom) r).sizeCat.connectionWeight(); j++){