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

View File

@ -68,61 +68,67 @@ public abstract class Builder {
}
}
//iterate through all rooms we are overlapping, and find which one would take
//the largest area reduction to resolve the overlapping
Room biggestCollision = null;
int wDiff, hDiff, biggestDiff = 0;
boolean widthCollision = false;
for (Room room : colliding){
//iterate through all rooms we are overlapping, and find the closest one
Room closestRoom = null;
int closestDiff = Integer.MAX_VALUE;
boolean inside = true;
int curDiff = 0;
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;
if (room.left >= start.x){
wDiff = (space.right - room.left) * (space.height() + 1);
} else if (room.right <= start.x){
wDiff = (room.right - space.left) * (space.height() + 1);
if (closestRoom.left >= start.x){
wDiff = (space.right - closestRoom.left) * (space.height() + 1);
} else if (closestRoom.right <= start.x){
wDiff = (closestRoom.right - space.left) * (space.height() + 1);
}
hDiff = Integer.MAX_VALUE;
if (room.top >= start.y){
hDiff = (space.bottom - room.top) * (space.width() + 1);
} else if (room.bottom <= start.y){
hDiff = (room.bottom - space.top) * (space.width() + 1);
if (closestRoom.top >= start.y){
hDiff = (space.bottom - closestRoom.top) * (space.width() + 1);
} else if (closestRoom.bottom <= start.y){
hDiff = (closestRoom.bottom - space.top) * (space.width() + 1);
}
//our start is inside this room, return an empty rect
if (hDiff == Integer.MAX_VALUE && wDiff == Integer.MAX_VALUE){
space.set(0, 0, 0, 0);
return space;
//reduce by as little as possible to resolve the collision
if (wDiff < hDiff || wDiff == hDiff && Random.Int(2) == 0){
if (closestRoom.left >= start.x && closestRoom.left < space.right) space.right = closestRoom.left;
if (closestRoom.right <= start.x && closestRoom.right > space.left) space.left = closestRoom.right;
} else {
if (wDiff < hDiff || (wDiff == hDiff && Random.Int(2) == 0)){
if (wDiff >= biggestDiff){
biggestDiff = wDiff;
biggestCollision = room;
widthCollision = true;
}
} else {
if (hDiff >= biggestDiff){
biggestDiff = hDiff;
biggestCollision = room;
widthCollision = false;
}
}
if (closestRoom.top >= start.y && closestRoom.top < space.bottom) space.bottom = closestRoom.top;
if (closestRoom.bottom <= start.y && closestRoom.bottom > space.top) space.top = closestRoom.bottom;
}
}
//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);
colliding.remove(closestRoom);
} else {
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 toCenter = new PointF((to.left + to.right)/2f, (to.top + to.bottom)/2f);
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

View File

@ -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;
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
if (!prev.connect(entrance)){
return null;
//FIXME this is still fairly chance reliant
// should just write a general function for stitching two rooms together in builder
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) {
float angle;
int tries = 10;
do {
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);

View File

@ -56,8 +56,8 @@ public abstract class RegularBuilder extends Builder {
return this;
}
protected float[] pathTunnelChances = new float[]{2, 3, 1};
protected float[] branchTunnelChances = new float[]{3, 2, 1};
protected float[] pathTunnelChances = new float[]{2, 6, 2};
protected float[] branchTunnelChances = new float[]{5, 4, 1};
public RegularBuilder setTunnelLength( float[] path, float[] branch){
pathTunnelChances = path;
@ -173,7 +173,7 @@ public abstract class RegularBuilder extends Builder {
continue;
}
branchable.addAll(connectingRoomsThisBranch);
if (Random.Float() < 0.33f) branchable.addAll(connectingRoomsThisBranch);
if (r.maxConnections(Room.ALL) > 1) {
if (r instanceof StandardRoom){
for (int j = 0; j < ((StandardRoom) r).sizeCat.connectionWeight(); j++){