From 01b4653938fe811450b805f394b880e4c8e31ea6 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Thu, 13 Apr 2017 00:10:33 -0400 Subject: [PATCH] v0.6.0: Implemented room initialization, converted loads of logic to new levelgen structure --- .../src/main/java/com/watabou/utils/Rect.java | 2 +- .../shatteredpixeldungeon/Dungeon.java | 10 +- .../actors/mobs/npcs/Blacksmith.java | 23 +--- .../actors/mobs/npcs/Wandmaker.java | 33 +---- .../levels/CavesLevel.java | 18 +++ .../levels/CityLevel.java | 10 ++ .../levels/HallsLevel.java | 11 +- .../levels/LastShopLevel.java | 28 +++- .../shatteredpixeldungeon/levels/Level.java | 2 - .../levels/PrisonLevel.java | 18 +++ .../levels/RegularLevel.java | 59 ++++++--- .../levels/SewerBossLevel.java | 99 +++------------ .../levels/SewerLevel.java | 18 +++ .../levels/builders/LegacyBuilder.java | 31 ++--- .../levels/builders/LineBuilder.java | 5 +- .../levels/painters/RegularPainter.java | 2 - .../levels/rooms/special/MagicWellRoom.java | 9 +- .../levels/rooms/special/ShopRoom.java | 6 + .../levels/rooms/special/SpecialRoom.java | 120 ++++++++++++++---- .../{special => standard}/BlacksmithRoom.java | 18 ++- .../rooms/standard/SewerBossEntranceRoom.java | 86 +++++++++++++ 21 files changed, 397 insertions(+), 211 deletions(-) rename core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/{special => standard}/BlacksmithRoom.java (86%) create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/SewerBossEntranceRoom.java diff --git a/SPD-classes/src/main/java/com/watabou/utils/Rect.java b/SPD-classes/src/main/java/com/watabou/utils/Rect.java index c43724dcb..808d7631b 100644 --- a/SPD-classes/src/main/java/com/watabou/utils/Rect.java +++ b/SPD-classes/src/main/java/com/watabou/utils/Rect.java @@ -134,7 +134,7 @@ public class Rect { } public ArrayList getPoints() { - ArrayList points = new ArrayList<>(square()*2); + ArrayList points = new ArrayList<>(); for (int i = left; i <= right; i++) for (int j = top; j <= bottom; j++) points.add(new Point(i, j)); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java index 83f1eb507..e2fa10d2e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java @@ -76,8 +76,6 @@ import java.util.HashSet; public class Dungeon { - public static int transmutation; // depth number for a well of transmutation - //enum of items which have limited spawns, records how many have spawned //could all be their own separate numbers, but this allows iterating, much nicer for bundling/initializing. //TODO: this is fairly brittle when it comes to bundling, should look into a more flexible solution. @@ -156,9 +154,7 @@ public class Dungeon { Potion.initColors(); Ring.initGems(); - transmutation = Random.IntRange( 6, 14 ); - - SpecialRoom.shuffleTypes(); + SpecialRoom.initForRun(); Random.seed(); @@ -454,8 +450,6 @@ public class Dungeon { quickslot.storePlaceholders( bundle ); - bundle.put( WT, transmutation ); - int[] dropValues = new int[limitedDrops.values().length]; for (limitedDrops value : limitedDrops.values()) dropValues[value.ordinal()] = value.count; @@ -563,8 +557,6 @@ public class Dungeon { quickslot.restorePlaceholders( bundle ); if (fullLoad) { - transmutation = bundle.getInt( WT ); - int[] dropValues = bundle.getIntArray(LIMDROPS); for (limitedDrops value : limitedDrops.values()) value.count = value.ordinal() < dropValues.length ? diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java index c80fe5f03..2d0863993 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java @@ -33,8 +33,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.quest.DarkGold; import com.shatteredpixel.shatteredpixeldungeon.items.quest.Pickaxe; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfUpgrade; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.BlacksmithRoom; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.BlacksmithRoom; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.BlacksmithSprite; @@ -279,27 +278,13 @@ public class Blacksmith extends NPC { } } - //FIXME: refactor this to work with new levelgen - public static boolean spawn( ArrayList rooms ) { + public static ArrayList spawn( ArrayList rooms ) { if (!spawned && Dungeon.depth > 11 && Random.Int( 15 - Dungeon.depth ) == 0) { - Room blacksmith; - for (Room r : rooms) { - if (r instanceof StandardRoom && r.width() >= 6 && r.height() >= 6) { - blacksmith = new BlacksmithRoom().set(r); - rooms.set(rooms.indexOf(r), blacksmith); - - spawned = true; - alternative = Random.Int( 2 ) == 0; - - given = false; - - break; - } - } + rooms.add(new BlacksmithRoom()); } - return spawned; + return rooms; } } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Wandmaker.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Wandmaker.java index 5e2b747a9..41f1bc980 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Wandmaker.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Wandmaker.java @@ -37,7 +37,6 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.MassGraveRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.RotGardenRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.RitualSiteRoom; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.plants.Rotberry; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; @@ -283,8 +282,7 @@ public class Wandmaker extends NPC { } } - //FIXME: refactor this to work with new levelgen - public static boolean spawnRoom( ArrayList rooms) { + public static ArrayList spawnRoom( ArrayList rooms) { questRoomSpawned = false; if (!spawned && (type != 0 || (Dungeon.depth > 6 && Random.Int( 10 - Dungeon.depth ) == 0))) { @@ -292,41 +290,22 @@ public class Wandmaker extends NPC { // but if the no herbalism challenge is enabled, only pick 1 or 2, no rotberry. if (type == 0) type = Random.Int(Dungeon.isChallenged(Challenges.NO_HERBALISM) ? 2 : 3)+1; - //note that we set the type but can fail here. This ensures that if a level needs to be re-generated - //we don't re-roll the quest, it will try to assign itself to that new level with the same type. - Room questRoom = null; - for (Room r : rooms){ - if (r instanceof StandardRoom && r.width() >= 7 && r.height() >= 7){ - if (type == 2 || r.connected.size() == 1){ - questRoom = r; - break; - } - } - } - - if (questRoom == null){ - return false; - } - - Room temp = questRoom; switch (type){ case 1: default: - questRoom = new MassGraveRoom().set(temp); + rooms.add(new MassGraveRoom()); break; case 2: - questRoom = new RitualSiteRoom().set(temp); + rooms.add(new RitualSiteRoom()); break; case 3: - questRoom = new RotGardenRoom().set(temp); + rooms.add(new RotGardenRoom()); break; } - rooms.set(rooms.indexOf(temp), questRoom); questRoomSpawned = true; - return true; - } else { - return true; + } + return rooms; } public static void complete() { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CavesLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CavesLevel.java index 0ffa89607..e9e9aa677 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CavesLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CavesLevel.java @@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.levels; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith; import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom; @@ -56,6 +57,8 @@ import com.watabou.utils.PointF; import com.watabou.utils.Random; import com.watabou.utils.Rect; +import java.util.ArrayList; + public class CavesLevel extends RegularLevel { { @@ -65,6 +68,21 @@ public class CavesLevel extends RegularLevel { viewDistance = 6; } + @Override + protected ArrayList initRooms() { + return Blacksmith.Quest.spawn(super.initRooms()); + } + + @Override + protected int standardRooms() { + return 5+Random.chances(new float[]{2, 2, 3, 2, 1, 1}); + } + + @Override + protected int specialRooms() { + return 1+Random.chances(new float[]{3, 3, 2, 1}); + } + @Override public String tilesTex() { return Assets.TILES_CAVES; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CityLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CityLevel.java index 6222b95ca..22038eb82 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CityLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CityLevel.java @@ -58,6 +58,16 @@ public class CityLevel extends RegularLevel { color2 = 0xf2f2f2; } + @Override + protected int standardRooms() { + return 6+Random.chances(new float[]{2, 3, 3, 2, 1}); + } + + @Override + protected int specialRooms() { + return 1 + Random.chances(new float[]{2, 3, 3, 1}); + } + @Override public String tilesTex() { return Assets.TILES_CITY; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/HallsLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/HallsLevel.java index 4e98fb97b..115dee943 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/HallsLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/HallsLevel.java @@ -59,7 +59,6 @@ import javax.microedition.khronos.opengles.GL10; public class HallsLevel extends RegularLevel { { - minRoomSize = 7; viewDistance = Math.max( 25 - Dungeon.depth, 1 ); @@ -67,6 +66,16 @@ public class HallsLevel extends RegularLevel { color2 = 0xa68521; } + @Override + protected int standardRooms() { + return 8+Random.chances(new float[]{3, 3, 2, 2, 1}); + } + + @Override + protected int specialRooms() { + return 1 + Random.chances(new float[]{1, 3, 3, 2}); + } + @Override public void create() { addItemToSpawn( new Torch() ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastShopLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastShopLevel.java index 16ae9074c..c135f3d8a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastShopLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastShopLevel.java @@ -28,11 +28,17 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Imp; import com.shatteredpixel.shatteredpixeldungeon.items.Heap; import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.levels.builders.Builder; -import com.shatteredpixel.shatteredpixeldungeon.levels.builders.LegacyBuilder; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.ShopRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.EntranceRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.ExitRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.FissureRoom; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.watabou.noosa.Group; import com.watabou.utils.Random; +import java.util.ArrayList; + public class LastShopLevel extends RegularLevel { { @@ -50,11 +56,27 @@ public class LastShopLevel extends RegularLevel { return Assets.WATER_CITY; } + @Override + protected ArrayList initRooms() { + ArrayList rooms = new ArrayList<>(); + + rooms.add ( roomEntrance = new EntranceRoom()); + rooms.add( roomExit = new ExitRoom()); + + if (Imp.Quest.isCompleted()){ + rooms.add( new ShopRoom() ); + } else { + rooms.add( new FissureRoom() ); + } + + return rooms; + } + @Override protected Builder builder() { feeling = Feeling.CHASM; - return new LegacyBuilder(LegacyBuilder.Type.LAST_SHOP, - width, height, minRoomSize, maxRoomSize); + //TODO want to use strict line builder here + return super.builder(); } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java index 07443ca44..b076179b7 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java @@ -260,8 +260,6 @@ public abstract class Level implements Bundlable { } while (!build()); decorate(); - PathFinder.setMapSize(width(), height()); - buildFlagMaps(); cleanWalls(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonLevel.java index 2445c2eb4..f73c16954 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/PrisonLevel.java @@ -26,6 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Wandmaker; import com.shatteredpixel.shatteredpixeldungeon.effects.Halo; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.FlameParticle; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.AlarmTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ChillingTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ConfusionTrap; @@ -48,6 +49,8 @@ import com.watabou.noosa.particles.Emitter; import com.watabou.utils.PointF; import com.watabou.utils.Random; +import java.util.ArrayList; + public class PrisonLevel extends RegularLevel { { @@ -55,6 +58,21 @@ public class PrisonLevel extends RegularLevel { color2 = 0x88924c; } + @Override + protected ArrayList initRooms() { + return Wandmaker.Quest.spawnRoom(super.initRooms()); + } + + @Override + protected int standardRooms() { + return 4+Random.chances(new float[]{2, 3, 3, 2, 1}); + } + + @Override + protected int specialRooms() { + return 1+Random.chances(new float[]{4, 3, 3}); + } + @Override public String tilesTex() { return Assets.TILES_PRISON; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java index 8bbaf966f..8e2b895a2 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java @@ -33,11 +33,13 @@ import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfWealth; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll; import com.shatteredpixel.shatteredpixeldungeon.levels.builders.Builder; -import com.shatteredpixel.shatteredpixeldungeon.levels.builders.LegacyBuilder; +import com.shatteredpixel.shatteredpixeldungeon.levels.builders.LineBuilder; import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; import com.shatteredpixel.shatteredpixeldungeon.levels.painters.RegularPainter; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.PitRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.ShopRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.WeakFloorRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.EntranceRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.ExitRoom; @@ -70,25 +72,53 @@ public abstract class RegularLevel extends Level { builder = builder(); - rooms = builder.build(null); - if (rooms == null){ - return false; - } + ArrayList initRooms = initRooms(); + Collections.shuffle(initRooms); - roomEntrance = ((LegacyBuilder)builder).roomEntrance; - roomExit = ((LegacyBuilder)builder).roomExit; + do { + for (Room r : initRooms){ + r.neigbours.clear(); + r.connected.clear(); + } + rooms = builder.build(initRooms); + } while (rooms == null); - if (!painter().paint(this, rooms)){ - return false; - } + return painter().paint(this, rooms); - return true; + } + + protected ArrayList initRooms() { + ArrayList initRooms = new ArrayList<>(); + initRooms.add ( roomEntrance = new EntranceRoom()); + initRooms.add( roomExit = new ExitRoom()); + + int standards = standardRooms(); + for (int i = 0; i < standards; i++) + initRooms.add(StandardRoom.createRoom()); + + if (Dungeon.shopOnLevel()) + initRooms.add(new ShopRoom()); + + int specials = specialRooms(); + SpecialRoom.initForFloor(); + for (int i = 0; i < specials; i++) + initRooms.add(SpecialRoom.createRoom()); + + return initRooms; + } + + protected int standardRooms(){ + return 0; + } + + protected int specialRooms(){ + return 0; } protected Builder builder(){ - return new LegacyBuilder(LegacyBuilder.Type.REGULAR, - width, height, minRoomSize, maxRoomSize); + //TODO need a much better builder here + return new LineBuilder(); } protected Painter painter(){ @@ -137,9 +167,6 @@ public abstract class RegularLevel extends Level { return new float[]{1}; } - protected int minRoomSize = 8; - protected int maxRoomSize = 10; - @Override public int nMobs() { switch(Dungeon.depth) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java index 9f9cb0404..3698f3143 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java @@ -21,7 +21,6 @@ package com.shatteredpixel.shatteredpixeldungeon.levels; -import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Bones; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; @@ -30,17 +29,17 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; import com.shatteredpixel.shatteredpixeldungeon.items.Heap; import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.levels.builders.Builder; -import com.shatteredpixel.shatteredpixeldungeon.levels.builders.LegacyBuilder; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.RatKingRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.SewerBossEntranceRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom; -import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; -import com.watabou.noosa.Group; import com.watabou.utils.Bundle; -import com.watabou.utils.PathFinder; import com.watabou.utils.Random; -public class SewerBossLevel extends RegularLevel { +import java.util.ArrayList; + +public class SewerBossLevel extends SewerLevel { { color1 = 0x48763c; @@ -50,41 +49,26 @@ public class SewerBossLevel extends RegularLevel { private int stairs = 0; @Override - public String tilesTex() { - return Assets.TILES_SEWERS; + protected ArrayList initRooms() { + ArrayList initRooms = new ArrayList<>(); + initRooms.add ( roomEntrance = roomExit = new SewerBossEntranceRoom()); + + int standards = standardRooms(); + for (int i = 0; i < standards; i++) + initRooms.add(StandardRoom.createRoom()); + + initRooms.add(new RatKingRoom()); + return initRooms; } @Override - public String waterTex() { - return Assets.WATER_SEWERS; - } - - @Override - protected boolean build() { - - if (!super.build()) - return false; - - //sticks the exit in the room entrance. - exit = roomEntrance.top * width() + (roomEntrance.left + roomEntrance.right) / 2; - map[exit] = Terrain.LOCKED_EXIT; - - //make sure the exit is only visible in the entrance room. - int count = 0; - for (int i : PathFinder.NEIGHBOURS8){ - //exit must have exactly 3 non-wall tiles around it. - if (map[exit+i] != Terrain.WALL) - count++; - } - if (count > 3) - return false; - - return true; + protected int standardRooms() { + return 3+Random.chances(new float[]{4, 2, 2}); } protected Builder builder(){ - return new LegacyBuilder(LegacyBuilder.Type.SEWER_BOSS, - width, height, minRoomSize, maxRoomSize); + //TODO want to use a more simple circular builder here + return super.builder(); } @Override @@ -110,29 +94,6 @@ public class SewerBossLevel extends RegularLevel { protected int nTraps() { return 0; } - - @Override - protected void decorate() { - int start = roomExit.top * width() + roomExit.left + 1; - int end = start + roomExit.width() - 2; - for (int i=start; i < end; i++) { - if (i != exit && map[i] == Terrain.WALL) { - map[i] = Terrain.WALL_DECO; - map[i + width()] = Terrain.WATER; - } else { - map[i + width()] = Terrain.EMPTY; - } - } - - placeSign(); - } - - @Override - public Group addVisuals() { - super.addVisuals(); - SewerLevel.addSewerVisuals(this, visuals); - return visuals; - } @Override protected void createMobs() { @@ -209,26 +170,4 @@ public class SewerBossLevel extends RegularLevel { stairs = bundle.getInt( STAIRS ); roomExit = roomEntrance; } - - @Override - public String tileName( int tile ) { - switch (tile) { - case Terrain.WATER: - return Messages.get(SewerLevel.class, "water_name"); - default: - return super.tileName( tile ); - } - } - - @Override - public String tileDesc(int tile) { - switch (tile) { - case Terrain.EMPTY_DECO: - return Messages.get(SewerLevel.class, "empty_deco_desc"); - case Terrain.BOOKSHELF: - return Messages.get(SewerLevel.class, "bookshelf_desc"); - default: - return super.tileDesc( tile ); - } - } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerLevel.java index 5e0c2c4a9..d1d62033c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerLevel.java @@ -53,6 +53,24 @@ public class SewerLevel extends RegularLevel { color2 = 0x59994a; } + @Override + protected int standardRooms() { + if (Dungeon.depth == 1){ + return 5+Random.chances(new float[]{4, 3, 3}); + } else { + return 4+Random.chances(new float[]{2, 4, 2, 1}); + } + } + + @Override + protected int specialRooms() { + if (Dungeon.depth == 1){ + return 1; + } else { + return 1+Random.chances(new float[]{4, 4, 2}); + } + } + @Override public String tilesTex() { return Assets.TILES_SEWERS; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LegacyBuilder.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LegacyBuilder.java index 31a5a5465..906a43d08 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LegacyBuilder.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LegacyBuilder.java @@ -21,28 +21,11 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.builders; -import com.shatteredpixel.shatteredpixeldungeon.Challenges; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; -import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; -import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Imp; -import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Wandmaker; -import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.ArmoryRoom; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.CryptRoom; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.GardenRoom; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.LaboratoryRoom; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.LibraryRoom; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.MagicWellRoom; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.PitRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.RatKingRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.ShopRoom; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.StatueRoom; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.TreasuryRoom; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.VaultRoom; -import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.WeakFloorRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.EntranceRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.ExitRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom; @@ -58,6 +41,9 @@ import java.util.ListIterator; //This builder exactly mimics pre-0.6.0 levelgen, including all of its limitations //Currently implemented during this transition period, it will likely not survive to 0.6.0 release + +//this is now broken due to changes elsewhere and serves only as a reference for older logic. +//DO NOT USE, pending deletion before 0.6.0 release. public class LegacyBuilder extends Builder { public enum Type{ @@ -190,6 +176,7 @@ public class LegacyBuilder extends Builder { } } + /* specials = new ArrayList<>( SpecialRoom.SPECIALS ); if (Dungeon.bossLevel( Dungeon.depth + 1 )) { specials.remove( WeakFloorRoom.class ); @@ -201,19 +188,21 @@ public class LegacyBuilder extends Builder { if (Dungeon.isChallenged( Challenges.NO_HERBALISM )){ //sorry warden, no lucky sungrass or blandfruit seeds for you! specials.remove( GardenRoom.class ); - } + }*/ if (!assignRoomType()) return null; //Quest generation logic + //disabled due to incompatibilities with old logic + /* if (Dungeon.depth >= 6 && Dungeon.depth <= 9){ if (!Wandmaker.Quest.spawnRoom( rooms ) && Dungeon.depth == 9) return null; } else if (Dungeon.depth >= 11 && Dungeon.depth <= 14){ if (!Blacksmith.Quest.spawn( rooms ) && Dungeon.depth == 14) return null; - } + }*/ ArrayList resultRooms = new ArrayList<>(); for (Room r : rooms) @@ -478,6 +467,8 @@ public class LegacyBuilder extends Builder { boolean pitMade = false; ListIterator it = rooms.listIterator(); + + /* while (it.hasNext()) { Room r = it.next(); Room temp; @@ -555,7 +546,7 @@ public class LegacyBuilder extends Builder { } if (Level.pitRoomNeeded && !pitMade) return false; - + */ Class tunnelType = TunnelRoom.class; if ((Dungeon.depth > 5 && Dungeon.depth <= 10) || (Dungeon.depth > 15 && Dungeon.depth <= 20)){ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LineBuilder.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LineBuilder.java index d466b5735..9c9d442c0 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LineBuilder.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/builders/LineBuilder.java @@ -58,7 +58,7 @@ public class LineBuilder extends Builder { } } - if (entrance == null || exit == null){ + if (entrance == null){ return null; } @@ -80,6 +80,9 @@ public class LineBuilder extends Builder { Room curr = entrance; for (int i = 0; i <= roomsOnPath; i++){ + if (i == roomsOnPath && exit == null) + continue; + if (Random.Int(2) == 0){ TunnelRoom t = new TunnelRoom(); t.setSize(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/painters/RegularPainter.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/painters/RegularPainter.java index 97d719c22..b6b261497 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/painters/RegularPainter.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/painters/RegularPainter.java @@ -82,8 +82,6 @@ public class RegularPainter extends Painter { level.setSize(width+1, height+1); - PathFinder.setMapSize(level.width(), level.height()); - for (Room r : rooms) { placeDoors( r ); r.paint( level ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MagicWellRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MagicWellRoom.java index c75b1c897..6191008d0 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MagicWellRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MagicWellRoom.java @@ -21,7 +21,6 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special; -import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.WaterOfAwareness; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.WaterOfHealth; @@ -38,6 +37,8 @@ public class MagicWellRoom extends SpecialRoom { private static final Class[] WATERS = {WaterOfAwareness.class, WaterOfHealth.class, WaterOfTransmutation.class}; + public Class overrideWater = null; + public void paint( Level level ) { Painter.fill( level, this, Terrain.WALL ); @@ -48,12 +49,12 @@ public class MagicWellRoom extends SpecialRoom { @SuppressWarnings("unchecked") Class waterClass = - Dungeon.depth >= Dungeon.transmutation ? - WaterOfTransmutation.class : + overrideWater != null ? + overrideWater : (Class)Random.element( WATERS ); if (waterClass == WaterOfTransmutation.class) { - Dungeon.transmutation = Integer.MAX_VALUE; + SpecialRoom.disableGaranteedWell(); } WellWater water = (WellWater)level.blobs.get( waterClass ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/ShopRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/ShopRoom.java index effb3cb52..37f0a5ec0 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/ShopRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/ShopRoom.java @@ -92,6 +92,12 @@ public class ShopRoom extends SpecialRoom { return Math.max(7, (int)(Math.sqrt(itemsToSpawn.size())+3)); } + //FIXME this is messy, the floor 21 shop should probably just be its own class. + @Override + public int maxConnections(int direction) { + return Dungeon.depth == 21 ? 2 : 1; + } + @Override public int minHeight() { if (itemsToSpawn == null) generateItems(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/SpecialRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/SpecialRoom.java index ce902430d..19c656bdb 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/SpecialRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/SpecialRoom.java @@ -21,12 +21,17 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special; +import com.shatteredpixel.shatteredpixeldungeon.Challenges; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.WaterOfTransmutation; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; import com.watabou.utils.Bundle; import com.watabou.utils.Random; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; public class SpecialRoom extends Room { @@ -60,41 +65,112 @@ public class SpecialRoom extends Room { TreasuryRoom.class, TrapsRoom.class, StorageRoom.class, StatueRoom.class, LaboratoryRoom.class, VaultRoom.class ) ); - public static ArrayList> SPECIALS = new ArrayList<>(); + public static ArrayList> runSpecials = new ArrayList<>(); + public static ArrayList> floorSpecials = new ArrayList<>(); - public static void shuffleTypes() { - SPECIALS = (ArrayList>)ALL_SPEC.clone(); - int size = SPECIALS.size(); - for (int i=0; i < size - 1; i++) { - int j = Random.Int( i, size ); - if (j != i) { - Class c = SPECIALS.get( i ); - SPECIALS.set( i, SPECIALS.get( j ) ); - SPECIALS.set( j, c ); - } + private static int pitNeededDepth = Integer.MAX_VALUE; + private static int guaranteedWellDepth = Integer.MAX_VALUE; + + public static void initForRun() { + runSpecials = (ArrayList>)ALL_SPEC.clone(); + + //remove special rooms disallowed by challenges + if (Dungeon.isChallenged( Challenges.NO_ARMOR )){ + //no sense in giving an armor reward room on a run with no armor. + runSpecials.remove( CryptRoom.class ); + } + if (Dungeon.isChallenged( Challenges.NO_HERBALISM )){ + //sorry warden, no lucky sungrass or blandfruit seeds for you! + runSpecials.remove( GardenRoom.class ); + } + + guaranteedWellDepth = Random.IntRange( 6, 14 ); + Collections.shuffle(runSpecials); + } + + public static void initForFloor(){ + floorSpecials = (ArrayList>) runSpecials.clone(); + } + + private static void useType( Class type ) { + if (runSpecials.remove( type )) { + floorSpecials.remove( type ); + runSpecials.add( type ); } } - public static void useType( Class type ) { - if (SPECIALS.remove( type )) { - SPECIALS.add( type ); + public static void disableGaranteedWell(){ + guaranteedWellDepth = Integer.MAX_VALUE; + } + + public static SpecialRoom createRoom(){ + if (Dungeon.depth == pitNeededDepth){ + pitNeededDepth = -1; + + floorSpecials.remove( ArmoryRoom.class ); + floorSpecials.remove( CryptRoom.class ); + floorSpecials.remove( LaboratoryRoom.class ); + floorSpecials.remove( LibraryRoom.class ); + floorSpecials.remove( StatueRoom.class ); + floorSpecials.remove( TreasuryRoom.class ); + floorSpecials.remove( VaultRoom.class ); + floorSpecials.remove( WeakFloorRoom.class ); + + return new PitRoom(); + + //TODO should laboratory rooms be more common like this? + } else if (Dungeon.depth % 5 == 2 && floorSpecials.contains( LaboratoryRoom.class )) { + + useType(LaboratoryRoom.class); + return new LaboratoryRoom(); + + } else if (Dungeon.depth >= guaranteedWellDepth) { + useType( MagicWellRoom.class ); + + MagicWellRoom r = new MagicWellRoom(); + r.overrideWater = WaterOfTransmutation.class; + guaranteedWellDepth = Integer.MAX_VALUE; + return r; + + } else { + + if (Dungeon.bossLevel(Dungeon.depth + 1)){ + floorSpecials.remove(WeakFloorRoom.class); + } + + Room r = null; + try { + r = floorSpecials.get( Math.min( Random.Int( floorSpecials.size() ), Random.Int( floorSpecials.size() ) ) ).newInstance(); + } catch (Exception e) { + ShatteredPixelDungeon.reportException(e); + } + + if (r instanceof WeakFloorRoom){ + pitNeededDepth = Dungeon.depth + 1; + } + + useType( r.getClass() ); + return (SpecialRoom)r; + } } private static final String ROOMS = "special_rooms"; + private static final String PIT = "pit_needed"; + private static final String WELL = "guaranteed_well"; public static void restoreRoomsFromBundle( Bundle bundle ) { - if (bundle.contains( ROOMS )) { - SPECIALS.clear(); - for (Class type : bundle.getClassArray( ROOMS )) { - SPECIALS.add( type ); - } - } else { - shuffleTypes(); + runSpecials.clear(); + for (Class type : bundle.getClassArray( ROOMS )) { + runSpecials.add( type ); } + pitNeededDepth = bundle.getInt(PIT); + guaranteedWellDepth = bundle.getInt(WELL); } public static void storeRoomsInBundle( Bundle bundle ) { - bundle.put( ROOMS, SPECIALS.toArray(new Class[0]) ); + bundle.put( ROOMS, runSpecials.toArray(new Class[0]) ); + bundle.put( PIT, pitNeededDepth ); + bundle.put( WELL, guaranteedWellDepth ); } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/BlacksmithRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/BlacksmithRoom.java similarity index 86% rename from core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/BlacksmithRoom.java rename to core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/BlacksmithRoom.java index 848c62c9e..f7c1ac144 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/BlacksmithRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/BlacksmithRoom.java @@ -19,7 +19,7 @@ * along with this program. If not, see */ -package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special; +package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith; import com.shatteredpixel.shatteredpixeldungeon.items.Generator; @@ -30,9 +30,19 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.traps.FireTrap; import com.watabou.utils.Point; import com.watabou.utils.Random; -public class BlacksmithRoom extends SpecialRoom { - - public void paint( Level level ) { +public class BlacksmithRoom extends StandardRoom { + + @Override + public int minWidth() { + return Math.max(super.minWidth(), 6); + } + + @Override + public int minHeight() { + return Math.max(super.minHeight(), 6); + } + + public void paint(Level level ) { Painter.fill( level, this, Terrain.WALL ); Painter.fill( level, this, 1, Terrain.TRAP ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/SewerBossEntranceRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/SewerBossEntranceRoom.java new file mode 100644 index 000000000..e11cc1d44 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/SewerBossEntranceRoom.java @@ -0,0 +1,86 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2017 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; + +public class SewerBossEntranceRoom extends EntranceRoom { + + @Override + public int minWidth() { + return 11; + } + + @Override + public int maxWidth() { + return 11; + } + + @Override + public int minHeight() { + return 5; + } + + @Override + public int maxHeight() { + return 8; + } + + //TODO perhaps I just want to deny all top-side connections + @Override + public boolean canConnect(Point p) { + //refuses connections on the center 3 tiles on the top side + return super.canConnect(p) + && !(p.y == top && p.x >= (left + (width()/2 - 1)) && p.x <= (left + (width()/2 + 1))); + } + + public void paint(Level level ) { + + Painter.fill( level, this, Terrain.WALL ); + Painter.fill( level, this, 1, Terrain.EMPTY ); + + Painter.fill( level, left+1, top+1, width()-2, 1, Terrain.WALL_DECO); + Painter.fill( level, left+1, top+2, width()-2, 1, Terrain.WATER); + + Painter.set( level, left+width()/2, top+1, Terrain.LOCKED_EXIT); + level.exit = level.pointToCell(new Point(left+width()/2, top+1)); + + do { + level.entrance = level.pointToCell(random(3)); + } while (level.findMob(level.entrance) != null); + Painter.set( level, level.entrance, Terrain.ENTRANCE ); + + for (Room.Door door : connected.values()) { + door.set( Room.Door.Type.REGULAR ); + + if (door.y == top){ + Painter.set( level, door.x, door.y+1, Terrain.WATER); + } + } + + } + +}