v1.2.0: finished new special rooms, plus a small tweak to storage rooms

This commit is contained in:
Evan Debenham 2022-03-14 19:22:44 -04:00
parent 5ebca6dcca
commit b9db0ce99d
9 changed files with 187 additions and 29 deletions

View File

@ -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 ) );

View File

@ -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;

View File

@ -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,11 +90,21 @@ 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());
@ -101,13 +113,20 @@ public class MagicalFireRoom extends SpecialRoom {
private static Item prize( Level level ) {
if (Random.Int(3) != 0){
Item prize = level.findPrizeItem();
//TODO prize!
if (prize != null)
return prize;
}
return Generator.random( Random.oneOf(
Generator.Category.POTION,
Generator.Category.SCROLL,
Generator.Category.FOOD,
Generator.Category.GOLD
) );
}
@Override
public boolean canPlaceGrass(Point p) {
return false;

View File

@ -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)

View File

@ -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)){

View File

@ -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<Class<? extends SpecialRoom>> 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<Class<? extends SpecialRoom>> CONSUMABLES_SPECIALS = new ArrayList<>( Arrays.asList(
RunestoneRoom.class, GardenRoom.class, LibraryRoom.class, StorageRoom.class, TreasuryRoom.class, MagicWellRoom.class
private static final ArrayList<Class<? extends SpecialRoom>> 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<Class<?extends Room>> runEquipSpecials = (ArrayList<Class<?extends Room>>)EQUIP_SPECIALS.clone();
ArrayList<Class<?extends Room>> runConsSpecials = (ArrayList<Class<?extends Room>>)CONSUMABLES_SPECIALS.clone();
ArrayList<Class<?extends Room>> runConsSpecials = (ArrayList<Class<?extends Room>>)CONSUMABLE_SPECIALS.clone();
Random.shuffle(runEquipSpecials);
Random.shuffle(runConsSpecials);

View File

@ -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,13 +44,14 @@ 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
} else {
level.drop( prize(level), pos);
}
}
entrance().set( Door.Type.BARRICADE );
level.addItemToSpawn( new PotionOfLiquidFlame() );
@ -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;

View File

@ -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<Integer> 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());

View File

@ -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)