v3.3.2: significantly improved early grid builder, still mostly random

This commit is contained in:
Evan Debenham
2026-01-02 11:56:26 -05:00
parent 218f668c8b
commit 6c69979e2d
2 changed files with 55 additions and 22 deletions

View File

@@ -54,7 +54,8 @@ public class VaultLevel extends CityLevel {
initRooms.add(roomEntrance = new EntranceRoom(){ initRooms.add(roomEntrance = new EntranceRoom(){
@Override @Override
public int maxConnections(int direction) { public int maxConnections(int direction) {
return 1; if (direction == LEFT || direction == TOP) return 0;
return super.maxConnections(direction);
} }
@Override @Override
@@ -73,6 +74,16 @@ public class VaultLevel extends CityLevel {
} }
initRooms.add(new RegionDecoLineRoom(){ initRooms.add(new RegionDecoLineRoom(){
@Override
public float[] sizeCatProbs() {
return new float[]{0, 0, 1};
}
@Override
public boolean isExit() {
return true;
}
@Override @Override
public int maxConnections(int direction) { public int maxConnections(int direction) {
return 1; return 1;
@@ -113,7 +124,8 @@ public class VaultLevel extends CityLevel {
((Armor) item).inscribe(null); ((Armor) item).inscribe(null);
} }
} }
item.identify(); //not true ID, prevents extra info about rings leaking to main game
item.levelKnown = item.cursedKnown = true;
addItemToSpawn(item); addItemToSpawn(item);
} }
@@ -184,8 +196,6 @@ public class VaultLevel extends CityLevel {
} }
} }
//TODO createItems will generate normal ones too =S
@Override @Override
public int randomRespawnCell( Char ch ) { public int randomRespawnCell( Char ch ) {
return entrance()-width(); return entrance()-width();

View File

@@ -61,27 +61,42 @@ public class GridBuilder extends Builder {
ArrayList<Room> toPlace = new ArrayList<>(rooms); ArrayList<Room> toPlace = new ArrayList<>(rooms);
toPlace.remove(entrance); toPlace.remove(entrance);
//move the exit to the back
if (exit != null) {
toPlace.remove(exit);
toPlace.add(exit);
}
ArrayList<Room> placed = new ArrayList<>(); ArrayList<Room> placed = new ArrayList<>();
placed.add(entrance); placed.add(entrance);
//use a sparse array to track room positions, with a mapping of x + 1000*y = cell //use a sparse array to track room positions, with a mapping of x + 1000*y = cell
//this assumes that levels won't more than 1000 rooms wide // and an index offset of 100,100 (x=y=100) to ensure we aren't dealing with negative indexes
//this effectively puts a limit of -99 < x < 999 and -99 < y < inf. on level sizes in rooms
SparseArray<Room> gridCells = new SparseArray<>(); SparseArray<Room> gridCells = new SparseArray<>();
gridCells.put(0, entrance); gridCells.put(100_100, entrance);
for (Room r : toPlace){ for (Room r : toPlace){
int cellWidth = 1;
int cellHeight = 1;
//TODO this works on rigid multiples atm, would be nicer to buffer rooms that don't quite work
if (!r.forceSize(ROOM_SIZE, ROOM_SIZE)){ if (!r.forceSize(ROOM_SIZE, ROOM_SIZE)){
throw new RuntimeException("rigid room sizes for now!"); if (!r.forceSize(2*ROOM_SIZE-1, 2*ROOM_SIZE-1)) {
throw new RuntimeException("rigid room sizes for now!");
}
cellWidth = cellHeight = 2;
} }
do { do {
Room n = Random.element(placed); r.neigbours.clear();
int nIdx = gridCells.findKey(n, true, Integer.MIN_VALUE); int[] keys = gridCells.keyArray();
int nIdx = keys[Random.Int(keys.length)];
Room n = gridCells.get(nIdx, null);
int rIdx = nIdx; int rIdx = nIdx;
switch (Random.Int(4)){ //currently always pulls down and to the right
case 0: switch (Random.Int(10)){
case 0: case 4: case 5: case 6:
rIdx += 1; rIdx += 1;
break; break;
case 1: case 1: case 7: case 8: case 9:
rIdx += 1000; rIdx += 1000;
break; break;
case 2: case 2:
@@ -91,23 +106,31 @@ public class GridBuilder extends Builder {
rIdx -= 1000; rIdx -= 1000;
break; break;
} }
//TODO negatives //-100 to cancel offsets
int x = rIdx%1000; int x = (rIdx % 1000) - 100;
int y = rIdx/1000; int y = (rIdx / 1000) - 100;
r.setPos(x*(ROOM_SIZE-1), y*(ROOM_SIZE-1)); r.setPos(x*(ROOM_SIZE-1), y*(ROOM_SIZE-1));
//TODO want to manually limit size probably boolean valid = true;
if (x >= 0 && y >= 0 && !gridCells.containsKey(rIdx)){ for (int i = 0; i < cellWidth; i++){
for (int j = 0; j < cellHeight; j++){
if (gridCells.containsKey(rIdx + i + j*1000)){
valid = false;
}
}
}
if (valid){
if (r.connect(n)) { if (r.connect(n)) {
placed.add(r); placed.add(r);
gridCells.put(rIdx, r); for (int i = 0; i < cellWidth; i++){
for (int j = 0; j < cellHeight; j++){
gridCells.put(rIdx + i + j*1000, r);
}
}
} }
} }
} while (!placed.contains(r)); } while (!placed.contains(r));
} }
//need a buffer room?
//contains an internal room, fills with
findNeighbours(rooms); findNeighbours(rooms);
for (Room r : rooms){ for (Room r : rooms){