diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/CrystalChoiceRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/CrystalChoiceRoom.java index 235f4347b..3c6ffefb5 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/CrystalChoiceRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/CrystalChoiceRoom.java @@ -22,6 +22,9 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.items.Generator; +import com.shatteredpixel.shatteredpixeldungeon.items.Heap; +import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.keys.CrystalKey; import com.shatteredpixel.shatteredpixeldungeon.items.keys.IronKey; import com.shatteredpixel.shatteredpixeldungeon.levels.Level; @@ -94,7 +97,36 @@ public class CrystalChoiceRoom extends SpecialRoom { Painter.fill(level, room1, Terrain.EMPTY_SP); Painter.fill(level, room2, Terrain.EMPTY_SP); - //TODO rewards + if (Random.Int(2) == 0){ + Room tmp = room1; + room1 = room2; + room2 = tmp; + } + + int n = Random.NormalIntRange(3, 4); + for (int i = 0; i < n; i++){ + Item reward = Generator.random(Random.oneOf( + Generator.Category.POTION, + Generator.Category.SCROLL + )); + int pos; + do { + if (room1.square() >= 16){ + pos = level.pointToCell(room1.random(1)); + } else { + pos = level.pointToCell(room1.random(0)); + } + } while (level.heaps.get(pos) != null); + level.drop(reward, pos); + } + + Item hidden = Generator.random(Random.oneOf( + Generator.Category.WAND, + Generator.Category.RING, + Generator.Category.ARTIFACT, + Generator.Category.GOLD //*evil laughter* + )); + level.drop(hidden, level.pointToCell(room2.center())).type = Heap.Type.CHEST; level.addItemToSpawn( new CrystalKey( Dungeon.depth ) ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/CrystalPathRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/CrystalPathRoom.java index 8c8f2918b..c8965606a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/CrystalPathRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/CrystalPathRoom.java @@ -22,6 +22,9 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.items.Generator; +import com.shatteredpixel.shatteredpixeldungeon.items.Gold; +import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.keys.CrystalKey; import com.shatteredpixel.shatteredpixeldungeon.items.keys.IronKey; import com.shatteredpixel.shatteredpixeldungeon.levels.Level; @@ -30,6 +33,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.EmptyRoom; import com.watabou.utils.Point; +import com.watabou.utils.Random; public class CrystalPathRoom extends SpecialRoom { @@ -123,7 +127,39 @@ public class CrystalPathRoom extends SpecialRoom { for (int i = 0; i < 4; i++){ int pos = level.pointToCell(rooms[idx].center()); - //TODO drop loot + Item item; + switch (i){ + case 0: default: + item = new Gold(Random.NormalIntRange(5, 12)); + break; + case 1: + if (Random.Int(3) == 0){ + item = level.findPrizeItem(); + if (item != null) break; + } + item = Generator.random(Random.oneOf( + Generator.Category.SEED, + Generator.Category.STONE) + ); + break; + case 2: + if (Random.Int(3) == 0){ + item = level.findPrizeItem(); + if (item != null) break; + } + item = Generator.random(Random.oneOf( + Generator.Category.POTION, + Generator.Category.SCROLL) + ); + break; + case 3: + item = Generator.random(Random.oneOf( + Generator.Category.WEAPON, + Generator.Category.ARMOR) + ); + break; + } + level.drop(item, pos); if (clockwise){ idx++; if (idx > 3) idx = 0; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MagicalFireRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MagicalFireRoom.java index 7384e6479..cb9b8438d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MagicalFireRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MagicalFireRoom.java @@ -33,7 +33,9 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Roots; import com.shatteredpixel.shatteredpixeldungeon.effects.BlobEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle; +import com.shatteredpixel.shatteredpixeldungeon.items.Generator; import com.shatteredpixel.shatteredpixeldungeon.items.Heap; +import com.shatteredpixel.shatteredpixeldungeon.items.Honeypot; import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfFrost; import com.shatteredpixel.shatteredpixeldungeon.levels.Level; @@ -88,24 +90,41 @@ public class MagicalFireRoom extends SpecialRoom { Painter.fill(level, behindFire, Terrain.EMPTY_SP); - int pos = level.pointToCell(Random.element(behindFire.getPoints())); - if (Random.Int( 3 ) == 0) { - level.drop( prize( level ), pos ).type = Heap.Type.CHEST; - } else { - level.drop( prize( level ), pos ).type = Heap.Type.CHEST; + boolean honeyPot = Random.Int( 2 ) == 0; + + int n = Random.IntRange( 3, 4 ); + n = Math.min(behindFire.square(), n); + + for (int i=0; i < n; i++) { + int pos; + do { + pos = level.pointToCell(behindFire.random(0)); + } while (level.heaps.get(pos) != null); + if (honeyPot){ + level.drop( new Honeypot(), pos); + honeyPot = false; + } else + level.drop( prize( level ), pos ); } level.addItemToSpawn(new PotionOfFrost()); } - private static Item prize(Level level ) { + private static Item prize( Level level ) { - Item prize = level.findPrizeItem(); + if (Random.Int(3) != 0){ + Item prize = level.findPrizeItem(); + if (prize != null) + return prize; + } - //TODO prize! - - return prize; + return Generator.random( Random.oneOf( + Generator.Category.POTION, + Generator.Category.SCROLL, + Generator.Category.FOOD, + Generator.Category.GOLD + ) ); } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/PoolRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/PoolRoom.java index 99b310eaa..485856051 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/PoolRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/PoolRoom.java @@ -102,6 +102,7 @@ public class PoolRoom extends SpecialRoom { Item prize; + //33% chance for prize item if (Random.Int(3) == 0){ prize = level.findPrizeItem(); if (prize != null) diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/SentryRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/SentryRoom.java index a92406f37..741f08efa 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/SentryRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/SentryRoom.java @@ -22,6 +22,7 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special; import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Challenges; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; @@ -30,6 +31,9 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Eye; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.NPC; import com.shatteredpixel.shatteredpixeldungeon.effects.Beam; import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile; +import com.shatteredpixel.shatteredpixeldungeon.items.Generator; +import com.shatteredpixel.shatteredpixeldungeon.items.Heap; +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; @@ -153,11 +157,40 @@ public class SentryRoom extends SpecialRoom { level.mobs.add( sentry ); Painter.set(level, treasurePos, Terrain.PEDESTAL); - //TODO reward + level.drop( prize( level ), level.pointToCell(treasurePos) ).type = Heap.Type.CHEST; entrance.set( Door.Type.REGULAR ); } + private static Item prize(Level level ) { + + Item prize; + + //50% chance for prize item + if (Random.Int(2) == 0){ + prize = level.findPrizeItem(); + if (prize != null) + return prize; + } + + //1 floor set higher in probability, never cursed + do { + if (Random.Int(2) == 0) { + prize = Generator.randomWeapon((Dungeon.depth / 5) + 1); + } else { + prize = Generator.randomArmor((Dungeon.depth / 5) + 1); + } + } while (prize.cursed || Challenges.isItemBlocked(prize)); + prize.cursedKnown = true; + + //33% chance for an extra update. + if (Random.Int(3) == 0){ + prize.upgrade(); + } + + return prize; + } + @Override public boolean canConnect(Point p) { if (!super.canConnect(p)){ 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 2468f5f0c..a1f2681f4 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 @@ -79,15 +79,19 @@ public abstract class SpecialRoom extends Room { } } - //special rooms which give an equipment reward + //10 special rooms which give equipment more often than consumables (or as often as) private static final ArrayList> EQUIP_SPECIALS = new ArrayList<>( Arrays.asList( - WeakFloorRoom.class, CryptRoom.class, PoolRoom.class, ArmoryRoom.class, TrapsRoom.class, StatueRoom.class, CrystalVaultRoom.class + WeakFloorRoom.class, CryptRoom.class, PoolRoom.class, ArmoryRoom.class, SentryRoom.class, + StatueRoom.class, CrystalVaultRoom.class, CrystalPathRoom.class, CrystalChoiceRoom.class, + SacrificeRoom.class )); - //special rooms which give a consumable reward + //9 special rooms which give consumables more often than equipment //note that alchemy rooms are spawned separately - private static final ArrayList> CONSUMABLES_SPECIALS = new ArrayList<>( Arrays.asList( - RunestoneRoom.class, GardenRoom.class, LibraryRoom.class, StorageRoom.class, TreasuryRoom.class, MagicWellRoom.class + private static final ArrayList> CONSUMABLE_SPECIALS = new ArrayList<>( Arrays.asList( + RunestoneRoom.class, GardenRoom.class, LibraryRoom.class, StorageRoom.class, + TreasuryRoom.class, MagicWellRoom.class, ToxicGasRoom.class, MagicalFireRoom.class, + TrapsRoom.class ) ); //only one special that uses crystal keys per floor @@ -104,7 +108,7 @@ public abstract class SpecialRoom extends Room { runSpecials = new ArrayList<>(); ArrayList> runEquipSpecials = (ArrayList>)EQUIP_SPECIALS.clone(); - ArrayList> runConsSpecials = (ArrayList>)CONSUMABLES_SPECIALS.clone(); + ArrayList> runConsSpecials = (ArrayList>)CONSUMABLE_SPECIALS.clone(); Random.shuffle(runEquipSpecials); Random.shuffle(runConsSpecials); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/StorageRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/StorageRoom.java index f1341e68a..1546e9c71 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/StorageRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/StorageRoom.java @@ -34,10 +34,8 @@ public class StorageRoom extends SpecialRoom { public void paint( Level level ) { - final int floor = Terrain.EMPTY_SP; - Painter.fill( level, this, Terrain.WALL ); - Painter.fill( level, this, 1, floor ); + Painter.fill( level, this, 1, Terrain.EMPTY_SP ); boolean honeyPot = Random.Int( 2 ) == 0; @@ -46,12 +44,13 @@ public class StorageRoom extends SpecialRoom { int pos; do { pos = level.pointToCell(random()); - } while (level.map[pos] != floor); + } while (level.map[pos] != Terrain.EMPTY_SP || level.heaps.get(pos) != null); if (honeyPot){ level.drop( new Honeypot(), pos); honeyPot = false; - } else - level.drop( prize( level ), pos ); + } else { + level.drop( prize(level), pos); + } } entrance().set( Door.Type.BARRICADE ); @@ -60,7 +59,7 @@ public class StorageRoom extends SpecialRoom { private static Item prize( Level level ) { - if (Random.Int(2) != 0){ + if (Random.Int(3) != 0){ Item prize = level.findPrizeItem(); if (prize != null) return prize; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/ToxicGasRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/ToxicGasRoom.java index 4171e1db3..e24ddbc2e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/ToxicGasRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/ToxicGasRoom.java @@ -24,6 +24,9 @@ package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.ToxicGas; +import com.shatteredpixel.shatteredpixeldungeon.items.Gold; +import com.shatteredpixel.shatteredpixeldungeon.items.Heap; +import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfPurity; import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; @@ -32,6 +35,8 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.traps.Trap; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.watabou.utils.Point; +import java.util.ArrayList; + public class ToxicGasRoom extends SpecialRoom { @Override @@ -44,6 +49,8 @@ public class ToxicGasRoom extends SpecialRoom { Painter.fill( level, this, Terrain.WALL ); Painter.fill( level, this, 1, Terrain.EMPTY ); + Painter.set( level, center(), Terrain.STATUE ); + for (Point p : getPoints()){ int cell = level.pointToCell(p); if (level.map[cell] == Terrain.EMPTY) { @@ -58,14 +65,40 @@ public class ToxicGasRoom extends SpecialRoom { int cell; do { cell = level.pointToCell(random(2)); - } while (level.map[cell] == Terrain.INACTIVE_TRAP); + } while (level.map[cell] != Terrain.EMPTY); level.setTrap(new ToxicVent().reveal(), cell); Blob.seed(cell, 12, ToxicGasSeed.class, level); Painter.set(level, cell, Terrain.INACTIVE_TRAP); } - //TODO loot! - //perhaps 2-3 items around the center? + //skeleton with 2x gold, somewhat far from entry + //then 2 chests with regular gold (no mimics here) + //we generate excess positions to ensure skull is far from entrance + ArrayList goldPositions = new ArrayList<>(); + for (int i = 0; i < 8; i++){ + int posToAdd; + do { + posToAdd = level.pointToCell(random(2)); + } while (level.map[posToAdd] == Terrain.STATUE || goldPositions.contains(posToAdd)); + goldPositions.add(posToAdd); + } + + int furthestPos = -1; + int entryPos = level.pointToCell(entrance()); + for (int i : goldPositions){ + if (furthestPos == -1 || level.trueDistance(entryPos, i) > level.trueDistance(entryPos, furthestPos)){ + furthestPos = i; + } + } + + goldPositions.remove((Integer) furthestPos); + Item mainGold = new Gold().random(); + mainGold.quantity(mainGold.quantity()*2); + level.drop(mainGold, furthestPos).type = Heap.Type.SKELETON; + + for (int i = 0; i < 2; i++){ + level.drop(new Gold().random(), goldPositions.remove(0)).type = Heap.Type.CHEST; + } level.addItemToSpawn(new PotionOfPurity()); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/TrapsRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/TrapsRoom.java index f75312163..bb9f9a71a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/TrapsRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/TrapsRoom.java @@ -116,6 +116,7 @@ public class TrapsRoom extends SpecialRoom { Item prize; + //67% chance for prize item if (Random.Int(3) != 0){ prize = level.findPrizeItem(); if (prize != null)