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();
|
decorate();
|
||||||
|
|
||||||
PathFinder.setMapSize(width(), height());
|
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();
|
buildFlagMaps();
|
||||||
cleanWalls();
|
cleanWalls();
|
||||||
|
@ -292,6 +284,17 @@ public abstract class Level implements Bundlable {
|
||||||
visited = new boolean[length];
|
visited = new boolean[length];
|
||||||
mapped = new boolean[length];
|
mapped = new boolean[length];
|
||||||
Dungeon.visible = 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() {
|
public void reset() {
|
||||||
|
@ -315,11 +318,9 @@ public abstract class Level implements Bundlable {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bundle.contains("width") && bundle.contains("height")){
|
if (bundle.contains("width") && bundle.contains("height")){
|
||||||
width = bundle.getInt("width");
|
setSize( bundle.getInt("width"), bundle.getInt("height"));
|
||||||
height = bundle.getInt("height");
|
|
||||||
} else
|
} else
|
||||||
width = height = 32; //default sizes
|
setSize( 32, 32); //default sizes
|
||||||
length = width * height;
|
|
||||||
PathFinder.setMapSize(width(), height());
|
PathFinder.setMapSize(width(), height());
|
||||||
|
|
||||||
mobs = new HashSet<>();
|
mobs = new HashSet<>();
|
||||||
|
@ -594,17 +595,6 @@ public abstract class Level implements Bundlable {
|
||||||
|
|
||||||
protected void buildFlagMaps() {
|
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++) {
|
for (int i=0; i < length(); i++) {
|
||||||
int flags = Terrain.flags[map[i]];
|
int flags = Terrain.flags[map[i]];
|
||||||
passable[i] = (flags & Terrain.PASSABLE) != 0;
|
passable[i] = (flags & Terrain.PASSABLE) != 0;
|
||||||
|
|
|
@ -22,8 +22,12 @@
|
||||||
package com.shatteredpixel.shatteredpixeldungeon.levels.builders;
|
package com.shatteredpixel.shatteredpixeldungeon.levels.builders;
|
||||||
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
|
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.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
public abstract class Builder {
|
public abstract class Builder {
|
||||||
|
|
||||||
|
@ -34,4 +38,85 @@ public abstract class Builder {
|
||||||
//returns null on failure
|
//returns null on failure
|
||||||
public abstract ArrayList<Room> build(ArrayList<Room> rooms);
|
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.ExitRoom;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.tunnel.TunnelRoom;
|
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.tunnel.TunnelRoom;
|
||||||
|
import com.watabou.utils.Point;
|
||||||
import com.watabou.utils.Random;
|
import com.watabou.utils.Random;
|
||||||
|
import com.watabou.utils.Rect;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@ -73,7 +75,7 @@ public class LineBuilder extends Builder {
|
||||||
shop.connect(entrance);
|
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 = Math.min(standardsOnPath, standards.size());
|
||||||
|
|
||||||
//standardsOnPath = standards.size();
|
//standardsOnPath = standards.size();
|
||||||
|
@ -157,7 +159,7 @@ public class LineBuilder extends Builder {
|
||||||
if (!placeBranchRoom(up, curr, r, rooms)){
|
if (!placeBranchRoom(up, curr, r, rooms)){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (r instanceof StandardRoom) {
|
if (r instanceof StandardRoom && Random.Int(3) == 0) {
|
||||||
if (up) upBrancheable.add(r);
|
if (up) upBrancheable.add(r);
|
||||||
else downBrancheable.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){
|
private boolean placeBranchRoom(boolean up, Room curr, Room next, ArrayList<Room> collision){
|
||||||
next.setSize();
|
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);
|
next.setPos( curr.left + (curr.width()-next.width())/2, up ? curr.top - next.height()+1 : curr.bottom);
|
||||||
next.connect(curr);
|
|
||||||
return true;
|
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());
|
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 );
|
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()
|
if (minW < minWidth()
|
||||||
|| maxW > maxWidth()
|
|| maxW > maxWidth()
|
||||||
|| minH < minHeight()
|
|| minH < minHeight()
|
||||||
|| maxH > maxHeight()){
|
|| maxH > maxHeight()
|
||||||
|
|| minW > maxW
|
||||||
|
|| minH > maxH){
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
//subtract one because rooms are inclusive to their right and bottom sides
|
//subtract one because rooms are inclusive to their right and bottom sides
|
||||||
resize(left + Random.NormalIntRange(minW, maxW) - 1,
|
resize(Random.NormalIntRange(minW, maxW) - 1,
|
||||||
top + Random.NormalIntRange(minH, maxH) - 1);
|
Random.NormalIntRange(minH, maxH) - 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,7 +175,8 @@ public class InterlevelScene extends PixelScene {
|
||||||
String errorMsg;
|
String errorMsg;
|
||||||
if (error instanceof FileNotFoundException) errorMsg = Messages.get(this, "file_not_found");
|
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 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);
|
else throw new RuntimeException("fatal error occured while moving between floors", error);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user