v0.9.1: improved layout logic and added figure eight builder

This commit is contained in:
Evan Debenham 2020-10-24 18:52:49 -04:00
parent 5437e58045
commit 84450af30c
5 changed files with 73 additions and 50 deletions

View File

@ -37,6 +37,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.journal.GuidePage;
import com.shatteredpixel.shatteredpixeldungeon.items.keys.GoldenKey;
import com.shatteredpixel.shatteredpixeldungeon.journal.Document;
import com.shatteredpixel.shatteredpixeldungeon.levels.builders.Builder;
import com.shatteredpixel.shatteredpixeldungeon.levels.builders.FigureEightBuilder;
import com.shatteredpixel.shatteredpixeldungeon.levels.builders.LoopBuilder;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
@ -144,10 +145,18 @@ public abstract class RegularLevel extends Level {
}
protected Builder builder(){
return new LoopBuilder()
.setLoopShape( 2 ,
Random.Float(0.4f, 0.7f),
Random.Float(0f, 0.5f));
if (Random.Int(2) == 0){
return new LoopBuilder()
.setLoopShape( 2 ,
Random.Float(0f, 0.65f),
Random.Float(0f, 0.50f));
} else {
return new FigureEightBuilder()
.setLoopShape( 2 ,
Random.Float(0.3f, 0.8f),
0f);
}
}
protected abstract Painter painter();

View File

@ -83,7 +83,7 @@ public class SewerBossLevel extends SewerLevel {
protected Builder builder(){
return new FigureEightBuilder()
.setLoopShape( 2 , Random.Float(0.4f, 0.7f), Random.Float(0f, 0.5f))
.setLoopShape( 2 , Random.Float(0.3f, 0.8f), 0f)
.setPathLength(1f, new float[]{1})
.setTunnelLength(new float[]{1, 2}, new float[]{1});
}

View File

@ -80,36 +80,41 @@ public class FigureEightBuilder extends RegularBuilder {
public ArrayList<Room> build(ArrayList<Room> rooms) {
setupRooms(rooms);
//TODO might want to make this able to work without an exit. Probably a random room would be landmark and the landmark room would become exit
if (landmarkRoom == null){
//prefer large and giant standard rooms over others
for (Room r : multiConnections){
for (Room r : mainPathRooms){
if ( r.maxConnections(Room.ALL) >= 4 &&
(landmarkRoom == null || landmarkRoom.minWidth()*landmarkRoom.minHeight() < r.minWidth()*r.minHeight())){
landmarkRoom = r;
}
}
//add another room to the path to compensate
if (!multiConnections.isEmpty()){
mainPathRooms.add(multiConnections.remove(0));
}
}
if (multiConnections.contains(landmarkRoom)){
multiConnections.remove(landmarkRoom);
}
mainPathRooms.remove(landmarkRoom);
multiConnections.remove(landmarkRoom);
float startAngle = Random.Float(0, 180);
int roomsOnLoop = (int)(multiConnections.size()*pathLength) + Random.chances(pathLenJitterChances);
roomsOnLoop = Math.min(roomsOnLoop, multiConnections.size());
int roomsOnFirstLoop = mainPathRooms.size()/2;
if (mainPathRooms.size() % 2 == 1) roomsOnFirstLoop += Random.Int(2);
int roomsOnFirstLoop = roomsOnLoop/2;
if (roomsOnLoop % 2 == 1) roomsOnFirstLoop += Random.Int(2);
ArrayList<Room> roomsToLoop = (ArrayList<Room>) mainPathRooms.clone();
ArrayList<Room> firstLoopTemp = new ArrayList<>();
firstLoopTemp.add(landmarkRoom);
for (int i = 0; i < roomsOnFirstLoop; i++){
firstLoopTemp.add(roomsToLoop.remove(0));
}
firstLoopTemp.add((firstLoopTemp.size()+1)/2, entrance);
float[] pathTunnels = pathTunnelChances.clone();
firstLoop = new ArrayList<>();
float[] pathTunnels = pathTunnelChances.clone();
for (int i = 0; i <= roomsOnFirstLoop; i++){
if (i == 0)
firstLoop.add(landmarkRoom);
else
firstLoop.add(multiConnections.remove(0));
for (Room r : firstLoopTemp){
firstLoop.add(r);
int tunnels = Random.chances(pathTunnels);
if (tunnels == -1){
@ -122,16 +127,14 @@ public class FigureEightBuilder extends RegularBuilder {
firstLoop.add(ConnectionRoom.createRoom());
}
}
if (entrance != null) firstLoop.add((firstLoop.size()+1)/2, entrance);
int roomsOnSecondLoop = roomsOnLoop - roomsOnFirstLoop;
ArrayList<Room> secondLoopTemp = new ArrayList<>();
secondLoopTemp.add(landmarkRoom);
secondLoopTemp.addAll(roomsToLoop);
secondLoopTemp.add((secondLoopTemp.size()+1)/2, exit);
secondLoop = new ArrayList<>();
for (int i = 0; i <= roomsOnSecondLoop; i++){
if (i == 0)
secondLoop.add(landmarkRoom);
else
secondLoop.add(multiConnections.remove(0));
for (Room r : secondLoopTemp){
secondLoop.add(r);
int tunnels = Random.chances(pathTunnels);
if (tunnels == -1){
@ -144,7 +147,6 @@ public class FigureEightBuilder extends RegularBuilder {
secondLoop.add(ConnectionRoom.createRoom());
}
}
if (exit != null) secondLoop.add((secondLoop.size()+1)/2, exit);
landmarkRoom.setSize();
landmarkRoom.setPos(0, 0);

View File

@ -83,16 +83,13 @@ public class LoopBuilder extends RegularBuilder {
float startAngle = Random.Float(0, 360);
ArrayList<Room> loop = new ArrayList<>();
int roomsOnLoop = (int)(multiConnections.size()*pathLength) + Random.chances(pathLenJitterChances);
roomsOnLoop = Math.min(roomsOnLoop, multiConnections.size());
mainPathRooms.add(0, entrance);
mainPathRooms.add((mainPathRooms.size()+1)/2, exit);
ArrayList<Room> loop = new ArrayList<>();
float[] pathTunnels = pathTunnelChances.clone();
for (int i = 0; i <= roomsOnLoop; i++){
if (i == 0)
loop.add(entrance);
else
loop.add(multiConnections.remove(0));
for (Room r : mainPathRooms){
loop.add(r);
int tunnels = Random.chances(pathTunnels);
if (tunnels == -1){
@ -106,8 +103,6 @@ public class LoopBuilder extends RegularBuilder {
}
}
if (exit != null) loop.add((loop.size()+1)/2, exit);
Room prev = entrance;
float targetAngle;
for (int i = 1; i < loop.size(); i++){

View File

@ -83,6 +83,8 @@ public abstract class RegularBuilder extends Builder {
protected Room exit = null;
protected Room shop = null;
protected ArrayList<Room> mainPathRooms = new ArrayList<>();
protected ArrayList<Room> multiConnections = new ArrayList<>();
protected ArrayList<Room> singleConnections = new ArrayList<>();
@ -92,6 +94,7 @@ public abstract class RegularBuilder extends Builder {
}
entrance = exit = shop = null;
mainPathRooms.clear();
singleConnections.clear();
multiConnections.clear();
for (Room r : rooms){
@ -112,6 +115,20 @@ public abstract class RegularBuilder extends Builder {
weightRooms(multiConnections);
Random.shuffle(multiConnections);
multiConnections = new ArrayList<>(new LinkedHashSet<>(multiConnections));
//shuffle one more time to ensure that the actual ordering of the path doesn't put big rooms early
Random.shuffle(multiConnections);
int roomsOnMainPath = (int)(multiConnections.size()*pathLength) + Random.chances(pathLenJitterChances);
while (roomsOnMainPath > 0 && !multiConnections.isEmpty()){
Room r = multiConnections.remove(0);
if (r instanceof StandardRoom){
roomsOnMainPath -= ((StandardRoom) r).sizeCat.roomValue;
} else {
roomsOnMainPath--;
}
mainPathRooms.add(r);
}
}
// *** Branch Placement ***