v0.6.0: lots of line builder implementation and general improvements
This commit is contained in:
parent
f20a5c1dcf
commit
84c405ef2b
|
@ -261,14 +261,6 @@ public abstract class Level implements Bundlable {
|
|||
decorate();
|
||||
|
||||
PathFinder.setMapSize(width(), height());
|
||||
passable = new boolean[length()];
|
||||
losBlocking = new boolean[length()];
|
||||
flamable = new boolean[length()];
|
||||
secret = new boolean[length()];
|
||||
solid = new boolean[length()];
|
||||
avoid = new boolean[length()];
|
||||
water = new boolean[length()];
|
||||
pit = new boolean[length()];
|
||||
|
||||
buildFlagMaps();
|
||||
cleanWalls();
|
||||
|
@ -292,6 +284,17 @@ public abstract class Level implements Bundlable {
|
|||
visited = new boolean[length];
|
||||
mapped = new boolean[length];
|
||||
Dungeon.visible = new boolean[length];
|
||||
|
||||
fieldOfView = new boolean[length()];
|
||||
|
||||
passable = new boolean[length()];
|
||||
losBlocking = new boolean[length()];
|
||||
flamable = new boolean[length()];
|
||||
secret = new boolean[length()];
|
||||
solid = new boolean[length()];
|
||||
avoid = new boolean[length()];
|
||||
water = new boolean[length()];
|
||||
pit = new boolean[length()];
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
|
@ -315,11 +318,9 @@ public abstract class Level implements Bundlable {
|
|||
}
|
||||
|
||||
if (bundle.contains("width") && bundle.contains("height")){
|
||||
width = bundle.getInt("width");
|
||||
height = bundle.getInt("height");
|
||||
setSize( bundle.getInt("width"), bundle.getInt("height"));
|
||||
} else
|
||||
width = height = 32; //default sizes
|
||||
length = width * height;
|
||||
setSize( 32, 32); //default sizes
|
||||
PathFinder.setMapSize(width(), height());
|
||||
|
||||
mobs = new HashSet<>();
|
||||
|
@ -593,17 +594,6 @@ public abstract class Level implements Bundlable {
|
|||
}
|
||||
|
||||
protected void buildFlagMaps() {
|
||||
|
||||
fieldOfView = new boolean[length()];
|
||||
|
||||
passable = new boolean[length()];
|
||||
losBlocking = new boolean[length()];
|
||||
flamable = new boolean[length()];
|
||||
secret = new boolean[length()];
|
||||
solid = new boolean[length()];
|
||||
avoid = new boolean[length()];
|
||||
water = new boolean[length()];
|
||||
pit = new boolean[length()];
|
||||
|
||||
for (int i=0; i < length(); i++) {
|
||||
int flags = Terrain.flags[map[i]];
|
||||
|
|
|
@ -22,8 +22,12 @@
|
|||
package com.shatteredpixel.shatteredpixeldungeon.levels.builders;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
|
||||
import com.watabou.utils.Point;
|
||||
import com.watabou.utils.Random;
|
||||
import com.watabou.utils.Rect;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
public abstract class Builder {
|
||||
|
||||
|
@ -34,4 +38,85 @@ public abstract class Builder {
|
|||
//returns null on failure
|
||||
public abstract ArrayList<Room> build(ArrayList<Room> rooms);
|
||||
|
||||
protected Rect findFreeSpace(Point start, ArrayList<Room> rooms, int maxSize){
|
||||
Rect space = new Rect(start.x-maxSize, start.y-maxSize, start.x+maxSize, start.y+maxSize);
|
||||
|
||||
ArrayList<Room> colliding = new ArrayList<>(rooms);
|
||||
do{
|
||||
|
||||
//remove any rooms we aren't currently overlapping
|
||||
Iterator<Room> it = colliding.iterator();
|
||||
while (it.hasNext()){
|
||||
Room room = it.next();
|
||||
//if not colliding
|
||||
if ( Math.max(space.left, room.left) >= Math.min(space.right, room.right)
|
||||
|| Math.max(space.top, room.top) >= Math.min(space.bottom, room.bottom) ){
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
//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){
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
//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;
|
||||
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//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 {
|
||||
colliding.clear();
|
||||
}
|
||||
|
||||
//loop until we are no longer colliding with any rooms
|
||||
} while (!colliding.isEmpty());
|
||||
|
||||
return space;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,9 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.EntranceRo
|
|||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.ExitRoom;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.tunnel.TunnelRoom;
|
||||
import com.watabou.utils.Point;
|
||||
import com.watabou.utils.Random;
|
||||
import com.watabou.utils.Rect;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
@ -73,7 +75,7 @@ public class LineBuilder extends Builder {
|
|||
shop.connect(entrance);
|
||||
}
|
||||
|
||||
int standardsOnPath = standards.size()/2 + Random.Int(3) - 1;
|
||||
int standardsOnPath = standards.size()/5 + Random.Int(2);
|
||||
standardsOnPath = Math.min(standardsOnPath, standards.size());
|
||||
|
||||
//standardsOnPath = standards.size();
|
||||
|
@ -157,7 +159,7 @@ public class LineBuilder extends Builder {
|
|||
if (!placeBranchRoom(up, curr, r, rooms)){
|
||||
continue;
|
||||
}
|
||||
if (r instanceof StandardRoom) {
|
||||
if (r instanceof StandardRoom && Random.Int(3) == 0) {
|
||||
if (up) upBrancheable.add(r);
|
||||
else downBrancheable.add(r);
|
||||
}
|
||||
|
@ -169,11 +171,24 @@ public class LineBuilder extends Builder {
|
|||
}
|
||||
|
||||
private boolean placeBranchRoom(boolean up, Room curr, Room next, ArrayList<Room> collision){
|
||||
next.setSize();
|
||||
next.setPos( curr.left + (curr.width()-next.width())/2, up ? curr.top - next.height()+1 : curr.bottom);
|
||||
next.connect(curr);
|
||||
return true;
|
||||
Rect space = findFreeSpace(
|
||||
new Point( curr.left + curr.width()/2, up ? curr.top : curr.bottom),
|
||||
collision,
|
||||
Math.max(next.maxWidth(), next.maxHeight()));
|
||||
|
||||
if (next.setSizeWithLimit(space.width()+1,space.height()+1 )){
|
||||
next.setPos( curr.left + (curr.width()-next.width())/2, up ? curr.top - next.height()+1 : curr.bottom);
|
||||
|
||||
if (next.right > space.right){
|
||||
next.shift( space.right - next.right, 0);
|
||||
} else if (next.left < space.left){
|
||||
next.shift( space.left - next.left, 0);
|
||||
}
|
||||
|
||||
return next.connect(curr);
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -83,20 +83,36 @@ public class Room extends Rect implements Graph.Node, Bundlable {
|
|||
return setSize(minWidth(), maxWidth(), minHeight(), maxHeight());
|
||||
}
|
||||
|
||||
public boolean setSize( int w, int h){
|
||||
public boolean forceSize( int w, int h ){
|
||||
return setSize( w, w, h, h );
|
||||
}
|
||||
|
||||
public boolean setSize(int minW, int maxW, int minH, int maxH) {
|
||||
public boolean setSizeWithLimit( int w, int h ){
|
||||
if ( w < minWidth() || h < minHeight()) {
|
||||
return false;
|
||||
} else {
|
||||
setSize();
|
||||
|
||||
if (width() > w || height() > h){
|
||||
resize(Math.min(width(), w)-1, Math.min(height(), h)-1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean setSize(int minW, int maxW, int minH, int maxH) {
|
||||
if (minW < minWidth()
|
||||
|| maxW > maxWidth()
|
||||
|| minH < minHeight()
|
||||
|| maxH > maxHeight()){
|
||||
|| maxH > maxHeight()
|
||||
|| minW > maxW
|
||||
|| minH > maxH){
|
||||
return false;
|
||||
} else {
|
||||
//subtract one because rooms are inclusive to their right and bottom sides
|
||||
resize(left + Random.NormalIntRange(minW, maxW) - 1,
|
||||
top + Random.NormalIntRange(minH, maxH) - 1);
|
||||
resize(Random.NormalIntRange(minW, maxW) - 1,
|
||||
Random.NormalIntRange(minH, maxH) - 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,7 +175,8 @@ public class InterlevelScene extends PixelScene {
|
|||
String errorMsg;
|
||||
if (error instanceof FileNotFoundException) errorMsg = Messages.get(this, "file_not_found");
|
||||
else if (error instanceof IOException) errorMsg = Messages.get(this, "io_error");
|
||||
else if (error.getMessage().equals("old save")) errorMsg = Messages.get(this, "io_error");
|
||||
else if (error.getMessage() != null &&
|
||||
error.getMessage().equals("old save")) errorMsg = Messages.get(this, "io_error");
|
||||
|
||||
else throw new RuntimeException("fatal error occured while moving between floors", error);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user