v3.1.0: expanded standard rooms in the demon halls

This commit is contained in:
Evan Debenham
2025-04-30 14:49:28 -04:00
parent 150718e9b7
commit f055e5bb36
23 changed files with 322 additions and 26 deletions

View File

@@ -65,7 +65,7 @@ public class HallsPainter extends RegularPainter {
for (Room r : rooms) {
for (Room n : r.neigbours) {
if (!r.connected.containsKey( n )) {
mergeRooms(level, r, n, null, Terrain.CHASM);
mergeRooms(level, r, n, null, Random.Int(3) == 0 ? Terrain.REGION_DECO : Terrain.CHASM);
}
}
}

View File

@@ -28,6 +28,11 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
public class RegionDecoPatchRoom extends PatchRoom {
@Override
public float[] sizeCatProbs() {
return new float[]{4, 1, 0};
}
@Override
public int minHeight() {
return Math.max(5, super.minHeight());
@@ -40,14 +45,14 @@ public class RegionDecoPatchRoom extends PatchRoom {
@Override
protected float fill() {
//fill scales from ~30% at 4x4, to ~50% at 10x10
//fill scales from ~20% at 4x4, to ~40% at 10x10
int scale = Math.min(width()*height(), 10*10);
return 0.30f + scale/512f;
return 0.20f + scale/512f;
}
@Override
protected int clustering() {
return 2;
return 1;
}
@Override

View File

@@ -29,7 +29,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.watabou.utils.Point;
import com.watabou.utils.Random;
public class RitualRoom extends StandardRoom {
public class RitualRoom extends PatchRoom {
@Override
public int minWidth() {
@@ -43,7 +43,33 @@ public class RitualRoom extends StandardRoom {
@Override
public float[] sizeCatProbs() {
return new float[]{2, 1, 0};
return new float[]{6, 3, 1};
}
@Override
protected float fill() {
//fill scales from ~30% at 4x4, to ~60% at 18x18
// normal ~30% to ~40%
// large ~40% to ~50%
// giant ~50% to ~60%
// however, the inner 7x7 is overridden, so overall fill is much lower
int scale = Math.min(width()*height(), 18*18);
return 0.30f + scale/1024f;
}
@Override
protected int clustering() {
return 0;
}
@Override
protected boolean ensurePath() {
return connected.size() > 0;
}
@Override
protected boolean cleanEdges() {
return true;
}
@Override
@@ -53,6 +79,11 @@ public class RitualRoom extends StandardRoom {
Point c = center();
setupPatch(level);
fillPatch(level, Terrain.REGION_DECO);
Painter.fill(level, c.x - 3, c.y - 3, 7, 7, Terrain.EMPTY);
Painter.set(level, c.x-2, c.y-1, Terrain.STATUE);
Painter.set(level, c.x-1, c.y-2, Terrain.STATUE);
Painter.set(level, c.x+2, c.y-1, Terrain.STATUE);
@@ -64,19 +95,6 @@ public class RitualRoom extends StandardRoom {
Painter.fill(level, c.x-1, c.y-1, 3, 3, Terrain.EMBERS);
Painter.set(level, c, Terrain.PEDESTAL);
if (width() >= 11 && height() >= 11){
Painter.set(level, left+2, top+2, Terrain.STATUE);
Painter.set(level, right-2, top+2, Terrain.STATUE);
Painter.set(level, left+2, bottom-2, Terrain.STATUE);
Painter.set(level, right-2, bottom-2, Terrain.STATUE);
if (width() >= 13 && height() >= 13){
Painter.set(level, left+3, top+3, Terrain.STATUE);
Painter.set(level, right-3, top+3, Terrain.STATUE);
Painter.set(level, left+3, bottom-3, Terrain.STATUE);
Painter.set(level, right-3, bottom-3, Terrain.STATUE);
}
}
placeloot(level, c);
for (Door door : connected.values()) {

View File

@@ -26,6 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room;
import com.watabou.utils.Point;
import com.watabou.utils.Random;
public class RuinsRoom extends PatchRoom {
@@ -73,6 +74,27 @@ public class RuinsRoom extends PatchRoom {
}
setupPatch(level);
fillPatch(level, Terrain.WALL);
for (int i = top + 1; i < bottom; i++) {
for (int j = left + 1; j < right; j++) {
if (patch[xyToPatchCoords(j, i)]) {
//isolated bits of wall are turned into rubble
boolean wall;
if (i > top+1 && i < bottom-1 && j >left+1 && j<right-1){
int adjacent = 0;
if (patch[xyToPatchCoords(j-1, i)]) adjacent++;
if (patch[xyToPatchCoords(j+1, i)]) adjacent++;
if (patch[xyToPatchCoords(j, i-1)]) adjacent++;
if (patch[xyToPatchCoords(j, i+1)]) adjacent++;
wall = Random.Int(2) < adjacent;
} else {
wall = true;
}
int cell = i * level.width() + j;
level.map[cell] = wall ? Terrain.WALL : Terrain.REGION_DECO;
}
}
}
}
}

View File

@@ -152,7 +152,7 @@ public abstract class StandardRoom extends Room {
rooms.add(ChasmRoom.class);
rooms.add(SkullsRoom.class);
rooms.add(RitualRoom.class);
rooms.add(EmptyRoom.class); //TODO
rooms.add(RegionDecoPatchRoom.class);
rooms.add(PlantsRoom.class);
@@ -183,7 +183,7 @@ public abstract class StandardRoom extends Room {
chances[16] = new float[]{0,0,5, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 10,5,5,5,10, 0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1};
chances[20] = chances[19] = chances[18] = chances[17] = chances[16];
chances[21] = new float[]{0,0,5, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 15,10,5,5,0, 1,1,1,1,1,1,1,1,1,1};
chances[21] = new float[]{0,0,5, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 11,8,5,5,8, 1,1,1,1,1,1,1,1,1,1};
chances[26] = chances[25] = chances[24] = chances[23] = chances[22] = chances[21];
}

View File

@@ -152,7 +152,7 @@ public class EntranceRoom extends StandardRoom {
rooms.add(ChasmEntranceRoom.class);
rooms.add(RitualEntranceRoom.class);
rooms.add(EntranceRoom.class); //TODO
rooms.add(RegionDecoPatchEntranceRoom.class);
}
private static float[][] chances = new float[27][];
@@ -172,7 +172,7 @@ public class EntranceRoom extends StandardRoom {
chances[16] = new float[]{0,0,3, 0,0,0, 0,0,0, 0,0,0, 3,2,2, 0,0,0};
chances[20] = chances[19] = chances[18] = chances[17] = chances[16];
chances[21] = new float[]{0,0,3, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 6,1,0};
chances[21] = new float[]{0,0,2, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 3,2,3};
chances[26] = chances[25] = chances[24] = chances[23] = chances[22] = chances[21];
}

View File

@@ -0,0 +1,80 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2025 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.entrance;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.RegionDecoPatchRoom;
import com.watabou.utils.PathFinder;
public class RegionDecoPatchEntranceRoom extends RegionDecoPatchRoom {
@Override
public int minHeight() {
return Math.max(7, super.minHeight());
}
@Override
public int minWidth() {
return Math.max(7, super.minWidth());
}
@Override
public boolean isEntrance() {
return true;
}
@Override
public void paint(Level level) {
super.paint(level);
int entrance;
int tries = 30;
boolean valid;
do {
entrance = level.pointToCell(random(2));
//need extra logic here as these rooms can spawn small and cramped in very rare cases
if (tries-- > 0){
valid = level.map[entrance] != Terrain.WALL && level.findMob(entrance) == null;
} else {
valid = false;
for (int i : PathFinder.NEIGHBOURS4){
if (level.map[entrance+i] != Terrain.WALL){
valid = true;
}
}
valid = valid && level.findMob(entrance) == null;
}
} while (!valid);
Painter.set( level, entrance, Terrain.ENTRANCE );
for (int i : PathFinder.NEIGHBOURS8){
Painter.set( level, entrance+i, Terrain.EMPTY );
}
level.transitions.add(new LevelTransition(level, entrance, LevelTransition.Type.REGULAR_ENTRANCE));
}
}

View File

@@ -30,6 +30,11 @@ import com.watabou.utils.Point;
public class RitualEntranceRoom extends RitualRoom {
@Override
public float[] sizeCatProbs() {
return new float[]{0, 1, 0};
}
@Override
public boolean isEntrance() {
return true;

View File

@@ -27,6 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.CavesFissureRoom;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Point;
public class CavesFissureExitRoom extends CavesFissureRoom {
@@ -64,4 +65,9 @@ public class CavesFissureExitRoom extends CavesFissureRoom {
}
@Override
public boolean canPlaceCharacter(Point p, Level l) {
return super.canPlaceCharacter(p, l) && l.pointToCell(p) != l.exit();
}
}

View File

@@ -27,6 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.ChasmBridgeRoom;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Point;
public class ChasmBridgeExitRoom extends ChasmBridgeRoom {
@@ -63,4 +64,9 @@ public class ChasmBridgeExitRoom extends ChasmBridgeRoom {
level.transitions.add(new LevelTransition(level, exit, LevelTransition.Type.REGULAR_EXIT));
}
@Override
public boolean canPlaceCharacter(Point p, Level l) {
return super.canPlaceCharacter(p, l) && l.pointToCell(p) != l.exit();
}
}

View File

@@ -27,6 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.ChasmRoom;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Point;
public class ChasmExitRoom extends ChasmRoom {
@@ -82,4 +83,9 @@ public class ChasmExitRoom extends ChasmRoom {
level.transitions.add(new LevelTransition(level, exit, LevelTransition.Type.REGULAR_EXIT));
}
@Override
public boolean canPlaceCharacter(Point p, Level l) {
return super.canPlaceCharacter(p, l) && l.pointToCell(p) != l.exit();
}
}

View File

@@ -26,6 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.CircleBasinRoom;
import com.watabou.utils.Point;
public class CircleBasinExitRoom extends CircleBasinRoom {
@@ -49,4 +50,9 @@ public class CircleBasinExitRoom extends CircleBasinRoom {
level.transitions.add(new LevelTransition(level, exit, LevelTransition.Type.REGULAR_EXIT));
}
@Override
public boolean canPlaceCharacter(Point p, Level l) {
return super.canPlaceCharacter(p, l) && l.pointToCell(p) != l.exit();
}
}

View File

@@ -84,4 +84,9 @@ public class CircleWallExitRoom extends CircleWallRoom {
}
}
@Override
public boolean canPlaceCharacter(Point p, Level l) {
return super.canPlaceCharacter(p, l) && l.pointToCell(p) != l.exit();
}
}

View File

@@ -94,7 +94,7 @@ public class ExitRoom extends StandardRoom {
rooms.add(ChasmExitRoom.class);
rooms.add(RitualExitRoom.class);
rooms.add(ExitRoom.class); //todo
rooms.add(RegionDecoPatchExitRoom.class);
}
private static float[][] chances = new float[27][];
@@ -113,7 +113,7 @@ public class ExitRoom extends StandardRoom {
chances[16] = new float[]{0,0,3, 0,0,0, 0,0,0, 0,0,0, 3,2,2, 0,0,0};
chances[20] = chances[19] = chances[18] = chances[17] = chances[16];
chances[21] = new float[]{0,0,3, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 6,1,0};
chances[21] = new float[]{0,0,2, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 3,2,3};
chances[26] = chances[25] = chances[24] = chances[23] = chances[22] = chances[21];
}

View File

@@ -52,4 +52,9 @@ public class HallwayExitRoom extends HallwayRoom {
}
@Override
public boolean canPlaceCharacter(Point p, Level l) {
return super.canPlaceCharacter(p, l) && l.pointToCell(p) != l.exit();
}
}

View File

@@ -77,4 +77,9 @@ public class LibraryRingExitRoom extends LibraryRingRoom {
}
}
@Override
public boolean canPlaceCharacter(Point p, Level l) {
return super.canPlaceCharacter(p, l) && l.pointToCell(p) != l.exit();
}
}

View File

@@ -27,6 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.PillarsRoom;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Point;
public class PillarsExitRoom extends PillarsRoom {
@@ -63,4 +64,9 @@ public class PillarsExitRoom extends PillarsRoom {
level.transitions.add(new LevelTransition(level, exit, LevelTransition.Type.REGULAR_EXIT));
}
@Override
public boolean canPlaceCharacter(Point p, Level l) {
return super.canPlaceCharacter(p, l) && l.pointToCell(p) != l.exit();
}
}

View File

@@ -0,0 +1,86 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2025 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.exit;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.RegionDecoPatchRoom;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Point;
public class RegionDecoPatchExitRoom extends RegionDecoPatchRoom {
@Override
public int minHeight() {
return Math.max(7, super.minHeight());
}
@Override
public int minWidth() {
return Math.max(7, super.minWidth());
}
@Override
public boolean isExit() {
return true;
}
@Override
public void paint(Level level) {
super.paint(level);
int exit;
int tries = 30;
boolean valid;
do {
exit = level.pointToCell(random(2));
//need extra logic here as these rooms can spawn small and cramped in very rare cases
if (tries-- > 0){
valid = level.map[exit] != Terrain.WALL && level.findMob(exit) == null;
} else {
valid = false;
for (int i : PathFinder.NEIGHBOURS4){
if (level.map[exit+i] != Terrain.WALL){
valid = true;
}
}
valid = valid && level.findMob(exit) == null;
}
} while (!valid);
Painter.set( level, exit, Terrain.EXIT );
for (int i : PathFinder.NEIGHBOURS8){
Painter.set( level, exit+i, Terrain.EMPTY );
}
level.transitions.add(new LevelTransition(level, exit, LevelTransition.Type.REGULAR_EXIT));
}
@Override
public boolean canPlaceCharacter(Point p, Level l) {
return super.canPlaceCharacter(p, l) && l.pointToCell(p) != l.exit();
}
}

View File

@@ -26,6 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.RingRoom;
import com.watabou.utils.Point;
public class RingExitRoom extends RingRoom {
@@ -49,4 +50,9 @@ public class RingExitRoom extends RingRoom {
level.transitions.add(new LevelTransition(level, pos, LevelTransition.Type.REGULAR_EXIT));
}
@Override
public boolean canPlaceCharacter(Point p, Level l) {
return super.canPlaceCharacter(p, l) && l.pointToCell(p) != l.exit();
}
}

View File

@@ -30,6 +30,11 @@ import com.watabou.utils.Point;
public class RitualExitRoom extends RitualRoom {
@Override
public float[] sizeCatProbs() {
return new float[]{0, 1, 0};
}
@Override
public boolean isExit() {
return true;
@@ -40,4 +45,9 @@ public class RitualExitRoom extends RitualRoom {
Painter.set(level, p, Terrain.EXIT);
level.transitions.add(new LevelTransition(level, level.pointToCell(p), LevelTransition.Type.REGULAR_EXIT));
}
@Override
public boolean canPlaceCharacter(Point p, Level l) {
return super.canPlaceCharacter(p, l) && l.pointToCell(p) != l.exit();
}
}

View File

@@ -26,6 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StatueLineRoom;
import com.watabou.utils.Point;
public class StatueLineExitRoom extends StatueLineRoom {
@@ -57,4 +58,10 @@ public class StatueLineExitRoom extends StatueLineRoom {
level.transitions.add(new LevelTransition(level, exit, LevelTransition.Type.REGULAR_EXIT));
}
@Override
public boolean canPlaceCharacter(Point p, Level l) {
return super.canPlaceCharacter(p, l) && l.pointToCell(p) != l.exit();
}
}

View File

@@ -27,6 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StatuesRoom;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Point;
public class StatuesExitRoom extends StatuesRoom {
@@ -61,4 +62,9 @@ public class StatuesExitRoom extends StatuesRoom {
}
@Override
public boolean canPlaceCharacter(Point p, Level l) {
return super.canPlaceCharacter(p, l) && l.pointToCell(p) != l.exit();
}
}

View File

@@ -27,6 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.WaterBridgeRoom;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Point;
public class WaterBridgeExitRoom extends WaterBridgeRoom {
@@ -63,4 +64,9 @@ public class WaterBridgeExitRoom extends WaterBridgeRoom {
level.transitions.add(new LevelTransition(level, exit, LevelTransition.Type.REGULAR_EXIT));
}
@Override
public boolean canPlaceCharacter(Point p, Level l) {
return super.canPlaceCharacter(p, l) && l.pointToCell(p) != l.exit();
}
}