diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/BridgeRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/BridgeRoom.java new file mode 100644 index 000000000..43f90410a --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/BridgeRoom.java @@ -0,0 +1,169 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2024 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.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; +import com.watabou.utils.Point; +import com.watabou.utils.Random; +import com.watabou.utils.Rect; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; + +public abstract class BridgeRoom extends StandardRoom { + + @Override + public int minWidth() { + return Math.max(5, super.minWidth()); + } + + @Override + public int minHeight() { + return Math.max(5, super.minHeight()); + } + + @Override + public boolean canMerge(Level l, Room other, Point p, int mergeTerrain) { + int cell = l.pointToCell(pointInside(p, 1)); + return l.map[cell] != spaceTile(); + } + + //keep these so that subclasses can use them in their methods + protected Rect spaceRect; + protected Rect bridgeRect; + + @Override + public void paint(Level level) { + Painter.fill( level, this, Terrain.WALL ); + Painter.fill( level, this, 1 , Terrain.EMPTY ); + + //prefer to place the bridge space to segment the most doors, or the most space in the room + int doorsXY = 0; + for (Door door : connected.values()) { + door.set( Door.Type.REGULAR ); + if (door.x == left || door.x == right){ + doorsXY++; + } else { + doorsXY--; + } + } + doorsXY += (width() - height())/2; + + if (doorsXY > 0 || (doorsXY == 0 && Random.Int(2) == 0)){ + + ArrayList spacePoints = new ArrayList<>(); + for (Door door : connected.values()) { + if (door.y == top || door.y == bottom){ + spacePoints.add(door); + } + } + + //add fake doors for very left/right + spacePoints.add(new Point(left+1, 0)); + spacePoints.add(new Point(right-1, 0)); + + Collections.sort(spacePoints, new Comparator() { + @Override + public int compare(Point d1, Point d2) { + return d1.x - d2.x; + } + }); + + int spaceStart = -1; + int spaceEnd = -1; + for (int i = 0; i < spacePoints.size()-1; i++){ + if (spaceEnd - spaceStart < spacePoints.get(i+1).x - spacePoints.get(i).x){ + spaceStart = spacePoints.get(i).x; + spaceEnd = spacePoints.get(i+1).x; + } + } + + while (spaceEnd - spaceStart > maxBridgeWidth(width())+1){ + if (Random.Int(2) == 0){ + spaceStart++; + } else { + spaceEnd--; + } + } + + spaceRect = new Rect(spaceStart+1, top+1, spaceEnd, bottom); + + int bridgeY = Random.NormalIntRange(spaceRect.top+1, spaceRect.bottom-2); + bridgeRect = new Rect(spaceRect.left, bridgeY, spaceRect.right, bridgeY+1); + + } else { + + ArrayList spacePoints = new ArrayList<>(); + for (Door door : connected.values()) { + if (door.x == left || door.x == right){ + spacePoints.add(door); + } + } + + //add fake doors for very top/bottom + spacePoints.add(new Point(0, top+1)); + spacePoints.add(new Point(0, bottom-1)); + + Collections.sort(spacePoints, new Comparator() { + @Override + public int compare(Point d1, Point d2) { + return d1.y - d2.y; + } + }); + + int spaceStart = -1; + int spaceEnd = -1; + for (int i = 0; i < spacePoints.size()-1; i++){ + if (spaceEnd - spaceStart < spacePoints.get(i+1).y - spacePoints.get(i).y){ + spaceStart = spacePoints.get(i).y; + spaceEnd = spacePoints.get(i+1).y; + } + } + + while (spaceEnd - spaceStart > maxBridgeWidth(height())+1){ + if (Random.Int(2) == 0){ + spaceStart++; + } else { + spaceEnd--; + } + } + + spaceRect = new Rect(left+1, spaceStart+1, right, spaceEnd); + + int bridgeX = Random.NormalIntRange(spaceRect.left+1, spaceRect.right-2); + bridgeRect = new Rect(bridgeX, spaceRect.top, bridgeX+1, spaceRect.bottom); + + } + + Painter.fill(level, spaceRect, spaceTile()); + Painter.fill(level, bridgeRect, Terrain.EMPTY_SP); + + } + + protected abstract int maxBridgeWidth( int roomDimension ); + + protected abstract int spaceTile(); +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/ChasmBridgeRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/ChasmBridgeRoom.java new file mode 100644 index 000000000..586df2563 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/ChasmBridgeRoom.java @@ -0,0 +1,36 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2024 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.Terrain; + +public class ChasmBridgeRoom extends BridgeRoom{ + + protected int maxBridgeWidth( int roomDimension ) { + return roomDimension >= 7 ? 2 : 1; + } + + protected int spaceTile(){ + return Terrain.CHASM; + } + +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/CircleWallRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/CircleWallRoom.java new file mode 100644 index 000000000..7623461ac --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/CircleWallRoom.java @@ -0,0 +1,52 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2024 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; + +public class CircleWallRoom extends StandardRoom { + + @Override + public float[] sizeCatProbs() { + return new float[]{0, 3, 1}; + } + + @Override + public void paint(Level level) { + Painter.fill( level, this, Terrain.WALL ); + + Painter.fillEllipse( level, this, 1 , Terrain.EMPTY ); + + for (Door door : connected.values()) { + door.set( Door.Type.REGULAR ); + if (door.x == left || door.x == right){ + Painter.drawInside(level, this, door, width()/2, Terrain.EMPTY); + } else { + Painter.drawInside(level, this, door, height()/2, Terrain.EMPTY); + } + } + + Painter.fillEllipse( level, this, 3 , Terrain.WALL ); + } +} \ No newline at end of file diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/LibraryRingRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/LibraryRingRoom.java new file mode 100644 index 000000000..9066284ba --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/LibraryRingRoom.java @@ -0,0 +1,79 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2024 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.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; +import com.watabou.utils.Point; +import com.watabou.utils.Rect; + +public class LibraryRingRoom extends StandardRoom { + + @Override + public int minWidth() { + return Math.max(super.minWidth(), 9); + } + + @Override + public int minHeight() { + return Math.max(super.minHeight(), 9); + } + + @Override + public float[] sizeCatProbs() { + return new float[]{4, 2, 1}; + } + + //cannot roll odd numbers if it is giant + @Override + public Rect resize(int w, int h) { + super.resize(w, h); + if (sizeCat == SizeCategory.GIANT) { + if (width() % 2 == 1) right--; + if (height() % 2 == 1) bottom--; + } + return this; + } + + @Override + public void paint(Level level) { + Painter.fill( level, this, Terrain.WALL ); + Painter.fill( level, this, 1 , Terrain.BOOKSHELF ); + Painter.fill( level, this, 2 , Terrain.EMPTY ); + + Painter.fill(level, this, 4, Terrain.BOOKSHELF); + + if (sizeCat == SizeCategory.GIANT){ + Point c = new Point((left + right) / 2, (top + bottom) / 2); //always round down + Painter.fill(level, c.x-4, c.y, 10, 2, Terrain.EMPTY); + Painter.fill(level, c.x, c.y-4, 2, 10, Terrain.EMPTY); + } + + for (Room.Door door : connected.values()) { + door.set( Room.Door.Type.REGULAR ); + Painter.drawInside(level, this, door, 2, Terrain.EMPTY); + } + } + +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/RitualRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/RitualRoom.java new file mode 100644 index 000000000..4e7b6941d --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/RitualRoom.java @@ -0,0 +1,96 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2024 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.items.Generator; +import com.shatteredpixel.shatteredpixeldungeon.items.Item; +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 RitualRoom extends StandardRoom { + + @Override + public int minWidth() { + return Math.max(super.minWidth(), 9); + } + + @Override + public int minHeight() { + return Math.max(super.minHeight(), 9); + } + + @Override + public float[] sizeCatProbs() { + 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 ); + + Point c = center(); + + 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); + Painter.set(level, c.x+1, c.y-2, Terrain.STATUE); + 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); + Painter.set(level, c.x+1, c.y+2, Terrain.STATUE); + 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()) { + door.set( Door.Type.REGULAR ); + } + } + + protected void placeloot(Level level, Point p){ + Item prize = Random.Int(2) == 0 ? level.findPrizeItem() : null; + + if (prize == null){ + prize = Generator.random( Random.oneOf(Generator.Category.POTION, Generator.Category.SCROLL)); + } + + level.drop(prize, level.pointToCell(p)); + } +} 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 4f469dbe9..88aa65e92 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 @@ -125,23 +125,28 @@ public abstract class StandardRoom extends Room { rooms.add(SewerPipeRoom.class); rooms.add(RingRoom.class); + rooms.add(WaterBridgeRoom.class); rooms.add(CircleBasinRoom.class); rooms.add(SegmentedRoom.class); rooms.add(PillarsRoom.class); + rooms.add(ChasmBridgeRoom.class); rooms.add(CellBlockRoom.class); rooms.add(CaveRoom.class); rooms.add(CavesFissureRoom.class); rooms.add(CirclePitRoom.class); + rooms.add(CircleWallRoom.class); rooms.add(HallwayRoom.class); rooms.add(StatuesRoom.class); + rooms.add(LibraryRingRoom.class); rooms.add(SegmentedLibraryRoom.class); rooms.add(RuinsRoom.class); rooms.add(ChasmRoom.class); rooms.add(SkullsRoom.class); + rooms.add(RitualRoom.class); rooms.add(PlantsRoom.class); @@ -158,21 +163,21 @@ public abstract class StandardRoom extends Room { private static float[][] chances = new float[27][]; static { - chances[1] = new float[]{10, 10,10,5, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 1,0,1,0,1,0,1,1,0,0}; - chances[2] = new float[]{10, 10,10,5, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 1,1,1,1,1,1,1,1,1,1}; + chances[1] = new float[]{5, 10,10,10,5, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 1,0,1,0,1,0,1,1,0,0}; + chances[2] = new float[]{5, 10,10,10,5, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 1,1,1,1,1,1,1,1,1,1}; chances[4] = chances[3] = chances[2]; - chances[5] = new float[]{10, 10,10,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0,0,0,0,0,0,0,0}; + chances[5] = new float[]{5, 10,10,10,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,0,0,0,0,0,0}; - chances[6] = new float[]{10, 0,0,0, 10,10,5, 0,0,0, 0,0,0, 0,0,0, 1,1,1,1,1,1,1,1,1,1}; + chances[6] = new float[]{5, 0,0,0,0, 10,10,10,5, 0,0,0,0, 0,0,0,0, 0,0,0,0, 1,1,1,1,1,1,1,1,1,1}; chances[10] = chances[9] = chances[8] = chances[7] = chances[6]; - chances[11] = new float[]{10, 0,0,0, 0,0,0, 10,10,5, 0,0,0, 0,0,0, 1,1,1,1,1,1,1,1,1,1}; + chances[11] = new float[]{5, 0,0,0,0, 0,0,0,0, 15,10,5,5, 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[]{10, 0,0,0, 0,0,0, 0,0,0, 10,10,5, 0,0,0, 1,1,1,1,1,1,1,1,1,1}; + chances[16] = new float[]{5, 0,0,0,0, 0,0,0,0, 0,0,0,0, 10,10,10,5, 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[]{10, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 10,10,5, 1,1,1,1,1,1,1,1,1,1}; + chances[21] = new float[]{5, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 15,10,5,5, 1,1,1,1,1,1,1,1,1,1}; chances[26] = chances[25] = chances[24] = chances[23] = chances[22] = chances[21]; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/WaterBridgeRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/WaterBridgeRoom.java new file mode 100644 index 000000000..33d78bbb0 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/WaterBridgeRoom.java @@ -0,0 +1,42 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2024 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.Terrain; +import com.watabou.utils.Point; + +public class WaterBridgeRoom extends BridgeRoom { + + protected int maxBridgeWidth( int roomDimension ) { + return roomDimension >= 8 ? 3 : 2; + } + + protected int spaceTile(){ + return Terrain.WATER; + } + + @Override + public boolean canPlaceWater(Point p) { + return false; + } + +}