v0.6.0: generalized branch placement logic

This commit is contained in:
Evan Debenham 2017-04-28 20:18:19 -04:00
parent 925d347b0d
commit 72808cdc17
3 changed files with 83 additions and 145 deletions

View File

@ -22,6 +22,7 @@
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.shatteredpixel.shatteredpixeldungeon.levels.rooms.tunnel.TunnelRoom;
import com.watabou.utils.GameMath; import com.watabou.utils.GameMath;
import com.watabou.utils.Point; import com.watabou.utils.Point;
import com.watabou.utils.PointF; import com.watabou.utils.PointF;
@ -241,4 +242,74 @@ public abstract class Builder {
return -1; return -1;
} }
} }
//places the rooms in roomsToBranch into branches from rooms in branchable.
//note that the three arrays should be separate, they may contain the same rooms however
protected static void createBranches( ArrayList<Room> rooms, ArrayList<Room> branchable,
ArrayList<Room> roomsToBranch, float[] tunnelChances){
int i = 0;
float angle;
int tries;
Room curr;
ArrayList<Room> tunnelsThisBranch = new ArrayList<>();
while (i < roomsToBranch.size()){
tunnelsThisBranch.clear();
curr = Random.element(branchable);
int tunnels = Random.chances(tunnelChances);
for (int j = 0; j < tunnels; j++){
TunnelRoom t = new TunnelRoom();
tries = 10;
do {
angle = placeRoom(rooms, curr, t, Random.Float(360f));
tries--;
} while (angle == -1 && tries >= 0);
if (angle == -1) {
for (Room r : tunnelsThisBranch){
r.clearConnections();
rooms.remove(r);
}
tunnelsThisBranch.clear();
break;
} else {
tunnelsThisBranch.add(t);
rooms.add(t);
}
curr = t;
}
if (tunnelsThisBranch.size() != tunnels){
continue;
}
Room r = roomsToBranch.get(i);
tries = 10;
do {
angle = placeRoom(rooms, curr, r, Random.Float(360f));
tries--;
} while (angle == -1 && tries >= 0);
if (angle == -1){
for (Room t : tunnelsThisBranch){
t.clearConnections();
rooms.remove(t);
}
tunnelsThisBranch.clear();
continue;
}
if (r.maxConnections(Room.ALL) > 1 && Random.Int(2) == 0)
branchable.add(r);
i++;
}
}
} }

View File

@ -130,74 +130,12 @@ public class LineBuilder extends Builder {
curr = r; curr = r;
} }
//place branches ArrayList<Room> roomsToBranch = new ArrayList<>();
int i = roomsOnPath; for (int i = roomsOnPath; i < multiConnections.size(); i++){
float angle; roomsToBranch.add(multiConnections.get(i));
int tries;
ArrayList<Room> tunnelsThisBranch = new ArrayList<>();
while (i < multiConnections.size() + singleConnections.size()){
tunnelsThisBranch.clear();
curr = Random.element(branchable);
int tunnels = Random.chances(branchTunnelChances);
for (int j = 0; j < tunnels; j++){
TunnelRoom t = new TunnelRoom();
tries = 10;
do {
angle = placeRoom(rooms, curr, t, Random.Float(360f));
tries--;
} while (angle == -1 && tries >= 0);
if (angle == -1) {
for (Room r : tunnelsThisBranch){
r.clearConnections();
rooms.remove(r);
}
tunnelsThisBranch.clear();
break;
} else {
tunnelsThisBranch.add(t);
rooms.add(t);
}
curr = t;
}
if (tunnelsThisBranch.size() != tunnels){
continue;
}
Room r;
if (i < multiConnections.size()) {
r = multiConnections.get(i);
} else {
r = singleConnections.get(i - multiConnections.size());
}
tries = 10;
do {
angle = placeRoom(rooms, curr, r, Random.Float(360f));
tries--;
} while (angle == -1 && tries >= 0);
if (angle == -1){
for (Room t : tunnelsThisBranch){
t.clearConnections();
rooms.remove(t);
}
tunnelsThisBranch.clear();
continue;
}
if (r.maxConnections(Room.ALL) > 1 && Random.Int(2) == 0)
branchable.add(r);
i++;
} }
roomsToBranch.addAll(singleConnections);
createBranches(rooms, branchable, roomsToBranch, branchTunnelChances);
findNeighbours(rooms); findNeighbours(rooms);

View File

@ -22,10 +22,9 @@
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.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.ShopRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.EmptyRoom;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.EntranceRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.EntranceRoom;
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.tunnel.TunnelRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.tunnel.TunnelRoom;
import com.watabou.utils.Random; import com.watabou.utils.Random;
@ -78,8 +77,6 @@ public class LoopBuilder extends Builder {
entrance = r; entrance = r;
} else if (r instanceof ExitRoom) { } else if (r instanceof ExitRoom) {
exit = r; exit = r;
} else if (r instanceof ShopRoom && r.maxConnections(Room.ALL) == 1){
shop = r;
} else if (r.maxConnections(Room.ALL) > 1){ } else if (r.maxConnections(Room.ALL) > 1){
multiConnections.add(r); multiConnections.add(r);
} else if (r.maxConnections(Room.ALL) == 1){ } else if (r.maxConnections(Room.ALL) == 1){
@ -122,9 +119,7 @@ public class LoopBuilder extends Builder {
for (int i = 0; i < loop.size(); i++){ for (int i = 0; i < loop.size(); i++){
Room r = loop.get(i); Room r = loop.get(i);
targetAngle += angleChange; targetAngle += angleChange;
float placeAngle; if (placeRoom(rooms, prev, r, targetAngle) != -1) {
if ((placeAngle = placeRoom(rooms, prev, r, targetAngle)) != -1) {
//targetAngle += (targetAngle - placeAngle);
prev = r; prev = r;
if (!rooms.contains(prev)) if (!rooms.contains(prev))
rooms.add(prev); rooms.add(prev);
@ -138,79 +133,13 @@ public class LoopBuilder extends Builder {
ArrayList<Room> branchable = new ArrayList<>(); ArrayList<Room> branchable = new ArrayList<>();
for (Room r : loop){ for (Room r : loop){
if (r instanceof StandardRoom) branchable.add(r); if (r instanceof EmptyRoom) branchable.add(r);
} }
int i = 0; ArrayList<Room> roomsToBranch = new ArrayList<>();
roomsToBranch.addAll(multiConnections);
Room curr; roomsToBranch.addAll(singleConnections);
float angle; createBranches(rooms, branchable, roomsToBranch, branchTunnelChances);
int tries;
ArrayList<Room> tunnelsThisBranch = new ArrayList<>();
//TODO this is almost identical to logic in linebuilder, can probably generalize
while (i < multiConnections.size() + singleConnections.size()){
tunnelsThisBranch.clear();
curr = Random.element(branchable);
int tunnels = Random.chances(branchTunnelChances);
for (int j = 0; j < tunnels; j++){
TunnelRoom t = new TunnelRoom();
tries = 10;
do {
angle = placeRoom(rooms, curr, t, Random.Float(360f));
tries--;
} while (angle == -1 && tries >= 0);
if (angle == -1) {
for (Room r : tunnelsThisBranch){
r.clearConnections();
rooms.remove(r);
}
tunnelsThisBranch.clear();
break;
} else {
tunnelsThisBranch.add(t);
rooms.add(t);
}
curr = t;
}
if (tunnelsThisBranch.size() != tunnels){
continue;
}
Room r;
if (i < multiConnections.size()) {
r = multiConnections.get(i);
} else {
r = singleConnections.get(i - multiConnections.size());
}
tries = 10;
do {
angle = placeRoom(rooms, curr, r, Random.Float(360f));
tries--;
} while (angle == -1 && tries >= 0);
if (angle == -1){
for (Room t : tunnelsThisBranch){
t.clearConnections();
rooms.remove(t);
}
tunnelsThisBranch.clear();
continue;
}
if (r.maxConnections(Room.ALL) > 1 && Random.Int(2) == 0)
branchable.add(r);
i++;
}
findNeighbours(rooms); findNeighbours(rooms);