v0.6.0: added connection limit logic for rooms
This commit is contained in:
parent
3c48ea8c3a
commit
9a902d97bd
|
@ -23,10 +23,8 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.builders;
|
|||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.ShopRoom;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.EntranceRoom;
|
||||
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;
|
||||
|
@ -42,8 +40,9 @@ public class LineBuilder extends Builder {
|
|||
Room entrance = null;
|
||||
Room exit = null;
|
||||
Room shop = null;
|
||||
ArrayList<StandardRoom> standards = new ArrayList<>();
|
||||
ArrayList<SpecialRoom> specials = new ArrayList<>();
|
||||
|
||||
ArrayList<Room> multiConnections = new ArrayList<>();
|
||||
ArrayList<Room> singleConnections = new ArrayList<>();
|
||||
|
||||
for (Room r : rooms){
|
||||
if (r instanceof EntranceRoom){
|
||||
|
@ -52,10 +51,10 @@ public class LineBuilder extends Builder {
|
|||
exit = r;
|
||||
} else if (r instanceof ShopRoom){
|
||||
shop = r;
|
||||
} else if (r instanceof StandardRoom){
|
||||
standards.add((StandardRoom)r);
|
||||
} else if (r instanceof SpecialRoom){
|
||||
specials.add((SpecialRoom)r);
|
||||
} else if (r.maxConnections(Room.ALL) > 1){
|
||||
multiConnections.add(r);
|
||||
} else if (r.maxConnections(Room.ALL) == 1){
|
||||
singleConnections.add(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,19 +70,17 @@ public class LineBuilder extends Builder {
|
|||
|
||||
if (shop != null){
|
||||
shop.setSize();
|
||||
shop.setPos(-shop.width(), -shop.height()/2);
|
||||
shop.setPos(-shop.width()+1, -shop.height()/2);
|
||||
shop.connect(entrance);
|
||||
}
|
||||
|
||||
int standardsOnPath = standards.size()/5 + Random.Int(2);
|
||||
standardsOnPath = Math.min(standardsOnPath, standards.size());
|
||||
|
||||
//standardsOnPath = standards.size();
|
||||
int roomsOnPath = multiConnections.size()/5 + Random.Int(2);
|
||||
roomsOnPath = Math.min(roomsOnPath, multiConnections.size());
|
||||
|
||||
Room curr = entrance;
|
||||
|
||||
for (int i = 0; i < standardsOnPath; i++){
|
||||
if (Random.Int(3) == 0){
|
||||
for (int i = 0; i <= roomsOnPath; i++){
|
||||
if (Random.Int(2) == 0){
|
||||
TunnelRoom t = new TunnelRoom();
|
||||
t.setSize();
|
||||
t.setPos( curr.right, -t.height()/2);
|
||||
|
@ -92,7 +89,7 @@ public class LineBuilder extends Builder {
|
|||
branchable.add(t);
|
||||
curr = t;
|
||||
}
|
||||
if (Random.Int(3) == 0){
|
||||
if (Random.Int(2) == 0){
|
||||
TunnelRoom t = new TunnelRoom();
|
||||
t.setSize();
|
||||
t.setPos( curr.right, -t.height()/2);
|
||||
|
@ -101,27 +98,26 @@ public class LineBuilder extends Builder {
|
|||
branchable.add(t);
|
||||
curr = t;
|
||||
}
|
||||
StandardRoom s = standards.get(i);
|
||||
s.setSize();
|
||||
s.setPos( curr.right, -s.height()/2);
|
||||
s.connect(curr);
|
||||
branchable.add(s);
|
||||
curr = s;
|
||||
Room r = (i == roomsOnPath ? exit : multiConnections.get(i));
|
||||
r.setSize();
|
||||
r.setPos( curr.right, -r.height()/2);
|
||||
r.connect(curr);
|
||||
branchable.add(r);
|
||||
curr = r;
|
||||
}
|
||||
|
||||
//place exit
|
||||
exit.setSize();
|
||||
exit.setPos( curr.right, -exit.height()/2);
|
||||
exit.connect(curr);
|
||||
branchable.add(exit);
|
||||
|
||||
ArrayList<Room> upBrancheable = new ArrayList<>(branchable);
|
||||
ArrayList<Room> downBrancheable = new ArrayList<>(branchable);
|
||||
|
||||
//place branches
|
||||
int i = standardsOnPath;
|
||||
while (i < standards.size() + specials.size()){
|
||||
boolean up = !upBrancheable.isEmpty() && (Random.Int(2) == 0 || downBrancheable.isEmpty());
|
||||
int i = roomsOnPath;
|
||||
while (i < multiConnections.size() + singleConnections.size()){
|
||||
if (upBrancheable.isEmpty() && downBrancheable.isEmpty())
|
||||
return null;
|
||||
|
||||
boolean up = downBrancheable.isEmpty()
|
||||
|| (Random.Int(2) == 0 && !upBrancheable.isEmpty());
|
||||
|
||||
if (up){
|
||||
curr = Random.element(upBrancheable);
|
||||
|
@ -131,7 +127,7 @@ public class LineBuilder extends Builder {
|
|||
downBrancheable.remove(curr);
|
||||
}
|
||||
|
||||
if (Random.Int(2) == 0){
|
||||
if (Random.Int(3) == 0){
|
||||
TunnelRoom t = new TunnelRoom();
|
||||
if (placeBranchRoom(up, curr, t, rooms)){
|
||||
rooms.add(t);
|
||||
|
@ -150,16 +146,16 @@ public class LineBuilder extends Builder {
|
|||
curr = t;
|
||||
}
|
||||
Room r;
|
||||
if (i < standards.size()) {
|
||||
r = standards.get(i);
|
||||
if (i < multiConnections.size()) {
|
||||
r = multiConnections.get(i);
|
||||
} else {
|
||||
r = specials.get(i - standards.size());
|
||||
r = singleConnections.get(i - multiConnections.size());
|
||||
}
|
||||
|
||||
if (!placeBranchRoom(up, curr, r, rooms)){
|
||||
continue;
|
||||
}
|
||||
if (r instanceof StandardRoom && Random.Int(3) == 0) {
|
||||
if (r.canConnect(up ? Room.TOP : Room.BOTTOM) && Random.Int(3) == 0) {
|
||||
if (up) upBrancheable.add(r);
|
||||
else downBrancheable.add(r);
|
||||
}
|
||||
|
|
|
@ -68,7 +68,13 @@ public class Room extends Rect implements Graph.Node, Bundlable {
|
|||
return this;
|
||||
}
|
||||
|
||||
//Note: when overriding these it is STRONGLY ADVISED to store any randomly decided values.
|
||||
//TODO make abstract
|
||||
public void paint(Level level){ }
|
||||
|
||||
|
||||
// **** Spatial logic ****
|
||||
|
||||
//Note: when overriding these YOU MUST store any randomly decided values.
|
||||
//With the same room and the same parameters these should always return
|
||||
//the same value over multiple calls, even if there's some randomness initially.
|
||||
public int minWidth(){
|
||||
|
@ -128,15 +134,78 @@ public class Room extends Rect implements Graph.Node, Bundlable {
|
|||
return super.height()+1;
|
||||
}
|
||||
|
||||
public void paint(Level level){ }
|
||||
|
||||
public Point random() {
|
||||
return random( 0 );
|
||||
return random( 1 );
|
||||
}
|
||||
|
||||
public Point random( int m ) {
|
||||
return new Point( Random.Int( left + 1 + m, right - m ),
|
||||
Random.Int( top + 1 + m, bottom - m ));
|
||||
return new Point( Random.Int( left + m, right - m ),
|
||||
Random.Int( top + m, bottom - m ));
|
||||
}
|
||||
|
||||
public boolean inside( Point p ) {
|
||||
return p.x > left && p.y > top && p.x < right && p.y < bottom;
|
||||
}
|
||||
|
||||
public Point center() {
|
||||
return new Point(
|
||||
(left + right) / 2 + (((right - left) % 2) == 1 ? Random.Int( 2 ) : 0),
|
||||
(top + bottom) / 2 + (((bottom - top) % 2) == 1 ? Random.Int( 2 ) : 0) );
|
||||
}
|
||||
|
||||
|
||||
// **** Connection logic ****
|
||||
|
||||
public static final int ALL = 0;
|
||||
public static final int LEFT = 1;
|
||||
public static final int TOP = 2;
|
||||
public static final int RIGHT = 3;
|
||||
public static final int BOTTOM = 4;
|
||||
|
||||
//TODO make abstract
|
||||
public int minConnections(int direction){ return -1; }
|
||||
|
||||
public int curConnections(int direction){
|
||||
if (direction == ALL) {
|
||||
return connected.size();
|
||||
|
||||
} else {
|
||||
int total = 0;
|
||||
for (Room r : connected.keySet()){
|
||||
Rect i = intersect( r );
|
||||
if (direction == LEFT && i.width() == 0 && i.left == left) total++;
|
||||
else if (direction == TOP && i.height() == 0 && i.top == top) total++;
|
||||
else if (direction == RIGHT && i.width() == 0 && i.right == right) total++;
|
||||
else if (direction == BOTTOM && i.height() == 0 && i.bottom == bottom) total++;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}
|
||||
|
||||
public int remConnections(int direction){
|
||||
if (curConnections(ALL) >= maxConnections(ALL)) return 0;
|
||||
else return maxConnections(direction) - curConnections(direction);
|
||||
}
|
||||
|
||||
//TODO make abstract
|
||||
public int maxConnections(int direction){ return -1; }
|
||||
|
||||
public boolean canConnect(int direction){
|
||||
return remConnections(direction) > 0;
|
||||
}
|
||||
|
||||
public boolean canConnect( Room r ){
|
||||
Rect i = intersect( r );
|
||||
if (i.width() == 0 && i.left == left)
|
||||
return canConnect(LEFT);
|
||||
else if (i.height() == 0 && i.top == top)
|
||||
return canConnect(TOP);
|
||||
else if (i.width() == 0 && i.right == right)
|
||||
return canConnect(RIGHT);
|
||||
else if (i.height() == 0 && i.bottom == bottom)
|
||||
return canConnect(BOTTOM);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean addNeigbour( Room other ) {
|
||||
|
@ -154,23 +223,13 @@ public class Room extends Rect implements Graph.Node, Bundlable {
|
|||
}
|
||||
|
||||
public boolean connect( Room room ) {
|
||||
if (!neigbours.contains(room) && !addNeigbour(room))
|
||||
return false;
|
||||
if (!connected.containsKey( room )) {
|
||||
if ((neigbours.contains(room) || addNeigbour(room))
|
||||
&& !connected.containsKey( room ) && canConnect(room) && room.canConnect(this)) {
|
||||
connected.put( room, null );
|
||||
room.connected.put( this, null );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean inside( Point p ) {
|
||||
return p.x > left && p.y > top && p.x < right && p.y < bottom;
|
||||
}
|
||||
|
||||
public Point center() {
|
||||
return new Point(
|
||||
(left + right) / 2 + (((right - left) % 2) == 1 ? Random.Int( 2 ) : 0),
|
||||
(top + bottom) / 2 + (((bottom - top) % 2) == 1 ? Random.Int( 2 ) : 0) );
|
||||
return false;
|
||||
}
|
||||
|
||||
// **** Graph.Node interface ****
|
||||
|
|
|
@ -57,7 +57,7 @@ public class BlacksmithRoom extends SpecialRoom {
|
|||
|
||||
Blacksmith npc = new Blacksmith();
|
||||
do {
|
||||
npc.pos = level.pointToCell(random( 1 ));
|
||||
npc.pos = level.pointToCell(random( 2 ));
|
||||
} while (level.heaps.get( npc.pos ) != null);
|
||||
level.mobs.add( npc );
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ public class RatKingRoom extends SpecialRoom {
|
|||
}
|
||||
|
||||
RatKing king = new RatKing();
|
||||
king.pos = level.pointToCell(random( 1 ));
|
||||
king.pos = level.pointToCell(random( 2 ));
|
||||
level.mobs.add( king );
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,17 @@ public class SpecialRoom extends Room {
|
|||
}
|
||||
public int maxHeight() { return 10; }
|
||||
|
||||
@Override
|
||||
public int minConnections(int direction) {
|
||||
if (direction == ALL) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int maxConnections(int direction) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Door entrance() {
|
||||
return connected.values().iterator().next();
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ public class EntranceRoom extends StandardRoom {
|
|||
}
|
||||
|
||||
do {
|
||||
level.entrance = level.pointToCell(random(1));
|
||||
level.entrance = level.pointToCell(random(2));
|
||||
} while (level.findMob(level.entrance) != null);
|
||||
Painter.set( level, level.entrance, Terrain.ENTRANCE );
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ public class ExitRoom extends StandardRoom {
|
|||
door.set( Room.Door.Type.REGULAR );
|
||||
}
|
||||
|
||||
level.exit = level.pointToCell(random( 1 ));
|
||||
level.exit = level.pointToCell(random( 2 ));
|
||||
Painter.set( level, level.exit, Terrain.EXIT );
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,18 @@ public abstract class StandardRoom extends Room {
|
|||
public int minHeight() { return sizeCat.minDim; }
|
||||
public int maxHeight() { return sizeCat.maxDim; }
|
||||
|
||||
@Override
|
||||
public int minConnections(int direction) {
|
||||
if (direction == ALL) return 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int maxConnections(int direction) {
|
||||
if (direction == ALL) return 16;
|
||||
else return 4;
|
||||
}
|
||||
|
||||
private static HashMap<Class<?extends StandardRoom>, Float> chances = new HashMap<>();
|
||||
|
||||
static {
|
||||
|
|
|
@ -37,6 +37,18 @@ public class TunnelRoom extends Room {
|
|||
public int minHeight() { return 3; }
|
||||
public int maxHeight() { return 10; }
|
||||
|
||||
@Override
|
||||
public int minConnections(int direction) {
|
||||
if (direction == ALL) return 2;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int maxConnections(int direction) {
|
||||
if (direction == ALL) return 16;
|
||||
else return 4;
|
||||
}
|
||||
|
||||
public void paint(Level level) {
|
||||
|
||||
int floor = level.tunnelTile();
|
||||
|
|
Loading…
Reference in New Issue
Block a user