From 150718e9b7b16fa66884ebeba21b3f191c8be066 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Mon, 28 Apr 2025 13:23:18 -0400 Subject: [PATCH] v3.1.0: expanded standard rooms in the metropolis --- .../levels/rooms/standard/HallwayRoom.java | 6 +- .../rooms/standard/LibraryHallRoom.java | 144 ++++++++++++++++++ .../levels/rooms/standard/StandardRoom.java | 4 +- .../levels/rooms/standard/StatuesRoom.java | 12 +- .../rooms/standard/entrance/EntranceRoom.java | 4 +- .../entrance/HallwayEntranceRoom.java | 3 +- .../entrance/LibraryRingEntranceRoom.java | 79 ++++++++++ .../levels/rooms/standard/exit/ExitRoom.java | 4 +- .../rooms/standard/exit/HallwayExitRoom.java | 3 +- .../standard/exit/LibraryRingExitRoom.java | 80 ++++++++++ 10 files changed, 329 insertions(+), 10 deletions(-) create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/LibraryHallRoom.java create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/entrance/LibraryRingEntranceRoom.java create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/exit/LibraryRingExitRoom.java diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/HallwayRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/HallwayRoom.java index 7339b94d6..9eaf1b5d0 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/HallwayRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/HallwayRoom.java @@ -103,7 +103,11 @@ public class HallwayRoom extends StandardRoom { } Painter.fill( level, c.left, c.top, 3, 3, Terrain.EMPTY_SP ); - Painter.fill( level, c.left+1, c.top+1, 1, 1, Terrain.STATUE_SP ); + if (Random.Int(2) == 0) { + Painter.fill(level, c.left + 1, c.top + 1, 1, 1, Terrain.STATUE_SP); + } else { + Painter.fill(level, c.left + 1, c.top + 1, 1, 1, Terrain.REGION_DECO_SP); + } for (Door door : connected.values()) { door.set( Door.Type.REGULAR ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/LibraryHallRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/LibraryHallRoom.java new file mode 100644 index 000000000..224e121dd --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/LibraryHallRoom.java @@ -0,0 +1,144 @@ +/* + * 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 + */ + +package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard; + +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; +import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; +import com.watabou.utils.Point; +import com.watabou.utils.Random; + +public class LibraryHallRoom extends StandardRoom { + + @Override + public int minWidth() { + return Math.max(7, super.minWidth()); + } + + @Override + public int minHeight() { + return Math.max(7, super.minHeight()); + } + + @Override + public float[] sizeCatProbs(){ + //TODO this room could probably have a giant variant? + // possible with three lines of bookcases instead of 2, and/or will holes in the middle + return new float[]{2, 1, 0}; + } + + @Override + public void paint(Level level) { + Painter.fill( level, this, Terrain.WALL ); + Painter.fill( level, this, 1 , Terrain.EMPTY ); + + //we decide which way to lay out the room based on a few factors: + float topBottomBooks = 0; + float leftRightBooks = 0; + + //primarily we decide based on whether it is taller or wider + if (width() > height()){ + topBottomBooks += (width() - height()); + } else if (height() > width()){ + leftRightBooks += (height() - width()); + } + + //but if one dimension is odd and the other's even, favor the odd one + if (width()%2 == 0 && height()%2 != 0){ + topBottomBooks += 2; + } else if (width()%2 != 0 && height()%2 == 0){ + leftRightBooks += 2; + } + + //lastly, if all else is equal, prefer to leave the sides with the most doors open + for (Door door : connected.values()) { + if (door.x == left || door.x == right){ + topBottomBooks += 0.1f; + } else { + leftRightBooks += 0.1f; + } + } + + boolean layingOutLeftToRight = topBottomBooks > leftRightBooks + || (topBottomBooks == leftRightBooks && Random.Int(2) == 0); + + int majorDim = layingOutLeftToRight ? height() : width(); + int minorDim = layingOutLeftToRight ? width() : height(); + + //if room is sufficiently small/big, place row of bookcases along edges + if (majorDim >= 11 || majorDim < 9){ + if (layingOutLeftToRight) { + Painter.drawLine(level, new Point(left + 1, top + 1), new Point(right - 1, top + 1), Terrain.BOOKSHELF); + Painter.drawLine(level, new Point(left + 1, bottom - 1), new Point(right - 1, bottom - 1), Terrain.BOOKSHELF); + } else { + Painter.drawLine(level, new Point(left+1, top+1), new Point(left+1, bottom-1), Terrain.BOOKSHELF); + Painter.drawLine(level, new Point(right-1, top+1), new Point(right-1, bottom-1), Terrain.BOOKSHELF); + } + + } + + Point center = center(); + + //if room is sufficiently big, place rows inset as well + int lengthInset = 2; + if (majorDim >= 9){ + if (minorDim >= 13){ + lengthInset++; + } + + if (layingOutLeftToRight) { + Painter.drawLine(level, new Point(left + lengthInset, center.y - 2), new Point(right - lengthInset, center.y - 2), Terrain.BOOKSHELF); + Painter.drawLine(level, new Point(left + lengthInset, center.y + 2), new Point(right - lengthInset, center.y + 2), Terrain.BOOKSHELF); + } else { + Painter.drawLine(level, new Point(center.x-2, top+lengthInset), new Point(center.x-2, bottom-lengthInset), Terrain.BOOKSHELF); + Painter.drawLine(level, new Point(center.x+2, top+lengthInset), new Point(center.x+2, bottom-lengthInset), Terrain.BOOKSHELF); + } + } + + if (minorDim % 2 == 1 && minorDim < 9){ + Painter.set(level, center, Terrain.REGION_DECO); + } else { + int pedestalInset = 2; + if (minorDim >= 10){ + pedestalInset++; + if (minorDim >= 13){ + pedestalInset++; + } + } + if (layingOutLeftToRight) { + Painter.set(level, left+pedestalInset, center.y, Terrain.REGION_DECO); + Painter.set(level, right-pedestalInset, center.y, Terrain.REGION_DECO); + } else { + Painter.set(level, center.x, top+pedestalInset, Terrain.REGION_DECO); + Painter.set(level, center.x, bottom-pedestalInset, Terrain.REGION_DECO); + } + } + + //ensure doors can still be accessed + for (Door door : connected.values()) { + Painter.drawInside(level, this, door, 1, Terrain.EMPTY); + door.set( Door.Type.REGULAR ); + } + + } + +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/StandardRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/StandardRoom.java index 217fa79c5..3811b1a58 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/StandardRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/StandardRoom.java @@ -146,7 +146,7 @@ public abstract class StandardRoom extends Room { rooms.add(StatuesRoom.class); rooms.add(LibraryRingRoom.class); rooms.add(SegmentedLibraryRoom.class); - rooms.add(EmptyRoom.class); //TODO + rooms.add(LibraryHallRoom.class); rooms.add(RuinsRoom.class); rooms.add(ChasmRoom.class); @@ -180,7 +180,7 @@ public abstract class StandardRoom extends Room { chances[11] = new float[]{0,5,0, 0,0,0,0,0, 0,0,0,0,0, 15,5,5,5,5, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1}; chances[15] = chances[14] = chances[13] = chances[12] = chances[11]; - chances[16] = new float[]{0,0,5, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 10,10,10,5,0, 0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1}; + 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}; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/StatuesRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/StatuesRoom.java index c42e8d09f..206d3f277 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/StatuesRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/StatuesRoom.java @@ -24,6 +24,7 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard; import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; +import com.watabou.utils.Random; public class StatuesRoom extends StandardRoom { @@ -73,8 +74,17 @@ public class StatuesRoom extends StandardRoom { Painter.set(level, left, top + h-1, Terrain.STATUE_SP); Painter.set(level, left + w-1, top + h-1, Terrain.STATUE_SP); + //place a flaming pedestal in the center if (w >= 5 && h >= 5){ - Painter.fill(level, left+2, top+2, w-4, h-4, Terrain.STATUE_SP); + int cx = left + w/2; + if (w % 2 == 0 && Random.Int(2) == 0){ + cx--; + } + int cy = top + h/2; + if (h % 2 == 0 && Random.Int(2) == 0){ + cy--; + } + Painter.set(level, cx, cy, Terrain.REGION_DECO_SP); } } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/entrance/EntranceRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/entrance/EntranceRoom.java index f764a3581..d92647a24 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/entrance/EntranceRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/entrance/EntranceRoom.java @@ -148,7 +148,7 @@ public class EntranceRoom extends StandardRoom { rooms.add(HallwayEntranceRoom.class); rooms.add(StatuesEntranceRoom.class); - rooms.add(EntranceRoom.class); //TODO + rooms.add(LibraryRingEntranceRoom.class); rooms.add(ChasmEntranceRoom.class); rooms.add(RitualEntranceRoom.class); @@ -169,7 +169,7 @@ public class EntranceRoom extends StandardRoom { chances[11] = new float[]{0,3,0, 0,0,0, 0,0,0, 3,2,2, 0,0,0, 0,0,0}; chances[15] = chances[14] = chances[13] = chances[12] = chances[11]; - chances[16] = new float[]{0,0,2, 0,0,0, 0,0,0, 0,0,0, 4,4,0, 0,0,0}; + 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}; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/entrance/HallwayEntranceRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/entrance/HallwayEntranceRoom.java index 779d25db1..db76c2d8f 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/entrance/HallwayEntranceRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/entrance/HallwayEntranceRoom.java @@ -41,7 +41,8 @@ public class HallwayEntranceRoom extends HallwayRoom { int entrance = -1; for ( Point p : getPoints()){ - if (level.map[level.pointToCell(p)] == Terrain.STATUE_SP){ + if (level.map[level.pointToCell(p)] == Terrain.STATUE_SP + || level.map[level.pointToCell(p)] == Terrain.REGION_DECO_SP){ entrance = level.pointToCell(p); break; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/entrance/LibraryRingEntranceRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/entrance/LibraryRingEntranceRoom.java new file mode 100644 index 000000000..29bcf27ba --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/entrance/LibraryRingEntranceRoom.java @@ -0,0 +1,79 @@ +/* + * 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 + */ + +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.LibraryRingRoom; +import com.watabou.utils.Point; +import com.watabou.utils.Random; + +public class LibraryRingEntranceRoom extends LibraryRingRoom { + + @Override + public int minWidth() { + return Math.max(super.minWidth(), 13); + } + + @Override + public int minHeight() { + return Math.max(super.minHeight(), 13); + } + + @Override + public float[] sizeCatProbs() { + return new float[]{0, 1, 0}; + } + + @Override + public boolean isEntrance() { + return true; + } + + @Override + public void paint(Level level) { + super.paint(level); + + Painter.fill(level, this, 5, Terrain.EMPTY_SP); + + Point p = center(); + Painter.set(level, p, Terrain.ENTRANCE_SP); + level.transitions.add(new LevelTransition(level, level.pointToCell(p), LevelTransition.Type.REGULAR_ENTRANCE)); + + int dirX = 0, dirY = 0; + if (Random.Int(2) == 0){ + dirX = Random.Int(2) == 0 ? +1 : -1; + } else { + dirY = Random.Int(2) == 0 ? +1 : -1; + } + + p.x += dirX; + p.y += dirY; + while (level.map[level.pointToCell(p)] != Terrain.EMPTY){ + Painter.set(level, p, Terrain.EMPTY_SP); + p.x += dirX; + p.y += dirY; + } + } +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/exit/ExitRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/exit/ExitRoom.java index bec1c4eed..17930161c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/exit/ExitRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/exit/ExitRoom.java @@ -90,7 +90,7 @@ public class ExitRoom extends StandardRoom { rooms.add(HallwayExitRoom.class); rooms.add(StatuesExitRoom.class); - rooms.add(ExitRoom.class); //todo + rooms.add(LibraryRingExitRoom.class); rooms.add(ChasmExitRoom.class); rooms.add(RitualExitRoom.class); @@ -110,7 +110,7 @@ public class ExitRoom extends StandardRoom { chances[11] = new float[]{0,2,0, 0,0,0, 0,0,0, 3,3,2, 0,0,0, 0,0,0}; chances[15] = chances[14] = chances[13] = chances[12] = chances[11]; - chances[16] = new float[]{0,0,2, 0,0,0, 0,0,0, 0,0,0, 4,4,0, 0,0,0}; + 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}; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/exit/HallwayExitRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/exit/HallwayExitRoom.java index 068e82a36..c37a41ef0 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/exit/HallwayExitRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/exit/HallwayExitRoom.java @@ -41,7 +41,8 @@ public class HallwayExitRoom extends HallwayRoom { int exit = -1; for ( Point p : getPoints()){ - if (level.map[level.pointToCell(p)] == Terrain.STATUE_SP){ + if (level.map[level.pointToCell(p)] == Terrain.STATUE_SP + || level.map[level.pointToCell(p)] == Terrain.REGION_DECO_SP){ exit = level.pointToCell(p); break; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/exit/LibraryRingExitRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/exit/LibraryRingExitRoom.java new file mode 100644 index 000000000..ef444cbe6 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/exit/LibraryRingExitRoom.java @@ -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 + */ + +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.LibraryRingRoom; +import com.watabou.utils.Point; +import com.watabou.utils.Random; + +public class LibraryRingExitRoom extends LibraryRingRoom { + + @Override + public int minWidth() { + return Math.max(super.minWidth(), 13); + } + + @Override + public int minHeight() { + return Math.max(super.minHeight(), 13); + } + + @Override + public float[] sizeCatProbs() { + return new float[]{0, 1, 0}; + } + + @Override + public boolean isExit() { + return true; + } + + @Override + public void paint(Level level) { + super.paint(level); + + Painter.fill(level, this, 5, Terrain.EMPTY_SP); + + Point p = center(); + Painter.set(level, p, Terrain.EXIT); + level.transitions.add(new LevelTransition(level, level.pointToCell(p), LevelTransition.Type.REGULAR_EXIT)); + + int dirX = 0, dirY = 0; + if (Random.Int(2) == 0){ + dirX = Random.Int(2) == 0 ? +1 : -1; + } else { + dirY = Random.Int(2) == 0 ? +1 : -1; + } + + p.x += dirX; + p.y += dirY; + while (level.map[level.pointToCell(p)] != Terrain.EMPTY){ + Painter.set(level, p, Terrain.EMPTY_SP); + p.x += dirX; + p.y += dirY; + } + } + +}