v0.9.1: added three new level feelings

This commit is contained in:
Evan Debenham 2020-10-18 19:35:55 -04:00
parent a861d52572
commit 01c22a454b
11 changed files with 120 additions and 61 deletions

View File

@ -29,7 +29,9 @@ scenes.gamescene.return=You return to floor %d of the dungeon.
scenes.gamescene.chasm=Your steps echo across the dungeon. scenes.gamescene.chasm=Your steps echo across the dungeon.
scenes.gamescene.water=You hear water splashing around you. scenes.gamescene.water=You hear water splashing around you.
scenes.gamescene.grass=The smell of vegetation is thick in the air. scenes.gamescene.grass=The smell of vegetation is thick in the air.
scenes.gamescene.dark=You can hear enemies moving in the darkness... scenes.gamescene.dark=You can hear enemies moving in the darkness.
scenes.gamescene.large=This dungeon floor seems unusually large.
scenes.gamescene.traps=The ground seems especially treacherous here.
scenes.gamescene.secrets=The atmosphere hints that this floor hides many secrets. scenes.gamescene.secrets=The atmosphere hints that this floor hides many secrets.
scenes.gamescene.choose_examine=Choose Examine scenes.gamescene.choose_examine=Choose Examine
scenes.gamescene.multiple_examine=There are multiple things of interest here, which one do you want to examine? scenes.gamescene.multiple_examine=There are multiple things of interest here, which one do you want to examine?

View File

@ -62,13 +62,15 @@ public class CavesLevel extends RegularLevel {
} }
@Override @Override
protected int standardRooms() { protected int standardRooms(boolean forceMax) {
if (forceMax) return 9;
//6 to 9, average 7.333 //6 to 9, average 7.333
return 6+Random.chances(new float[]{2, 3, 3, 1}); return 6+Random.chances(new float[]{2, 3, 3, 1});
} }
@Override @Override
protected int specialRooms() { protected int specialRooms(boolean forceMax) {
if (forceMax) return 3;
//1 to 3, average 2.2 //1 to 3, average 2.2
return 1+Random.chances(new float[]{2, 4, 4}); return 1+Random.chances(new float[]{2, 4, 4});
} }

View File

@ -57,13 +57,15 @@ public class CityLevel extends RegularLevel {
} }
@Override @Override
protected int standardRooms() { protected int standardRooms(boolean forceMax) {
if (forceMax) return 10;
//7 to 10, average 7.9 //7 to 10, average 7.9
return 7+Random.chances(new float[]{4, 3, 2, 1}); return 7+Random.chances(new float[]{4, 3, 2, 1});
} }
@Override @Override
protected int specialRooms() { protected int specialRooms(boolean forceMax) {
if (forceMax) return 3;
//2 to 3, average 2.33 //2 to 3, average 2.33
return 2 + Random.chances(new float[]{2, 1}); return 2 + Random.chances(new float[]{2, 1});
} }

View File

@ -81,13 +81,15 @@ public class HallsLevel extends RegularLevel {
} }
@Override @Override
protected int standardRooms() { protected int standardRooms(boolean forceMax) {
if (forceMax) return 10;
//8 to 10, average 8.67 //8 to 10, average 8.67
return 8+Random.chances(new float[]{3, 2, 1}); return 8+Random.chances(new float[]{3, 2, 1});
} }
@Override @Override
protected int specialRooms() { protected int specialRooms(boolean forceMax) {
if (forceMax) return 3;
//2 to 3, average 2.5 //2 to 3, average 2.5
return 2 + Random.chances(new float[]{1, 1}); return 2 + Random.chances(new float[]{1, 1});
} }

View File

@ -101,7 +101,10 @@ public abstract class Level implements Bundlable {
CHASM, CHASM,
WATER, WATER,
GRASS, GRASS,
DARK DARK,
LARGE,
TRAPS,
SECRETS
} }
protected int width; protected int width;
@ -209,23 +212,33 @@ public abstract class Level implements Bundlable {
} }
if (Dungeon.depth > 1) { if (Dungeon.depth > 1) {
switch (Random.Int( 10 )) { //50% chance of getting a level feeling
case 0: //~7.15% chance for each feeling
if (!Dungeon.bossLevel( Dungeon.depth + 1 )) { switch (Random.Int( 14 )) {
case 0:
feeling = Feeling.CHASM; feeling = Feeling.CHASM;
} break;
break; case 1:
case 1: feeling = Feeling.WATER;
feeling = Feeling.WATER; break;
break; case 2:
case 2: feeling = Feeling.GRASS;
feeling = Feeling.GRASS; break;
break; case 3:
case 3: feeling = Feeling.DARK;
feeling = Feeling.DARK; addItemToSpawn(new Torch());
addItemToSpawn(new Torch()); viewDistance = Math.round(viewDistance/2f);
viewDistance = Math.round(viewDistance/2f); break;
break; case 4:
feeling = Feeling.LARGE;
addItemToSpawn(Generator.random(Generator.Category.FOOD));
break;
case 5:
feeling = Feeling.TRAPS;
break;
case 6:
feeling = Feeling.SECRETS;
break;
} }
} }
} }

View File

@ -24,7 +24,6 @@ package com.shatteredpixel.shatteredpixeldungeon.levels;
import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Wandmaker; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Wandmaker;
import com.watabou.noosa.Halo;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.FlameParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.FlameParticle;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.PrisonPainter; import com.shatteredpixel.shatteredpixeldungeon.levels.painters.PrisonPainter;
@ -44,6 +43,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ToxicTrap;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap; import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
import com.watabou.noosa.Group; import com.watabou.noosa.Group;
import com.watabou.noosa.Halo;
import com.watabou.noosa.particles.Emitter; import com.watabou.noosa.particles.Emitter;
import com.watabou.utils.PointF; import com.watabou.utils.PointF;
import com.watabou.utils.Random; import com.watabou.utils.Random;
@ -63,13 +63,15 @@ public class PrisonLevel extends RegularLevel {
} }
@Override @Override
protected int standardRooms() { protected int standardRooms(boolean forceMax) {
if (forceMax) return 8;
//6 to 8, average 6.66 //6 to 8, average 6.66
return 6+Random.chances(new float[]{4, 2, 2}); return 6+Random.chances(new float[]{4, 2, 2});
} }
@Override @Override
protected int specialRooms() { protected int specialRooms(boolean forceMax) {
if (forceMax) return 3;
//1 to 3, average 1.83 //1 to 3, average 1.83
return 1+Random.chances(new float[]{3, 4, 3}); return 1+Random.chances(new float[]{3, 4, 3});
} }

View File

@ -95,8 +95,12 @@ public abstract class RegularLevel extends Level {
ArrayList<Room> initRooms = new ArrayList<>(); ArrayList<Room> initRooms = new ArrayList<>();
initRooms.add ( roomEntrance = new EntranceRoom()); initRooms.add ( roomEntrance = new EntranceRoom());
initRooms.add( roomExit = new ExitRoom()); initRooms.add( roomExit = new ExitRoom());
int standards = standardRooms(); //force max standard rooms and multiple by 1.5x for large levels
int standards = standardRooms(feeling == Feeling.LARGE);
if (feeling == Feeling.LARGE){
standards = (int)Math.ceil(standards * 1.5f);
}
for (int i = 0; i < standards; i++) { for (int i = 0; i < standards; i++) {
StandardRoom s; StandardRoom s;
do { do {
@ -108,8 +112,12 @@ public abstract class RegularLevel extends Level {
if (Dungeon.shopOnLevel()) if (Dungeon.shopOnLevel())
initRooms.add(new ShopRoom()); initRooms.add(new ShopRoom());
int specials = specialRooms(); //force max special rooms and add one more for large levels
int specials = specialRooms(feeling == Feeling.LARGE);
if (feeling == Feeling.LARGE){
specials++;
}
SpecialRoom.initForFloor(); SpecialRoom.initForFloor();
for (int i = 0; i < specials; i++) { for (int i = 0; i < specials; i++) {
SpecialRoom s = SpecialRoom.createRoom(); SpecialRoom s = SpecialRoom.createRoom();
@ -118,17 +126,20 @@ public abstract class RegularLevel extends Level {
} }
int secrets = SecretRoom.secretsForFloor(Dungeon.depth); int secrets = SecretRoom.secretsForFloor(Dungeon.depth);
for (int i = 0; i < secrets; i++) //one additional secret for secret levels
if (feeling == Feeling.SECRETS) secrets++;
for (int i = 0; i < secrets; i++) {
initRooms.add(SecretRoom.createRoom()); initRooms.add(SecretRoom.createRoom());
}
return initRooms; return initRooms;
} }
protected int standardRooms(){ protected int standardRooms(boolean forceMax){
return 0; return 0;
} }
protected int specialRooms(){ protected int specialRooms(boolean forceMax){
return 0; return 0;
} }
@ -155,13 +166,13 @@ public abstract class RegularLevel extends Level {
@Override @Override
public int nMobs() { public int nMobs() {
switch(Dungeon.depth) { if (Dungeon.depth <= 1) return 0;
case 1:
//mobs are not randomly spawned on floor 1. int mobs = 3 + Dungeon.depth % 5 + Random.Int(3);
return 0; if (feeling == Feeling.LARGE){
default: mobs = (int)Math.ceil(mobs * 1.33f);
return 3 + Dungeon.depth % 5 + Random.Int(3);
} }
return mobs;
} }
@Override @Override
@ -288,6 +299,10 @@ public abstract class RegularLevel extends Level {
// drops 3/4/5 items 60%/30%/10% of the time // drops 3/4/5 items 60%/30%/10% of the time
int nItems = 3 + Random.chances(new float[]{6, 3, 1}); int nItems = 3 + Random.chances(new float[]{6, 3, 1});
if (feeling == Feeling.LARGE){
nItems += 2;
}
for (int i=0; i < nItems; i++) { for (int i=0; i < nItems; i++) {

View File

@ -59,7 +59,7 @@ public class SewerBossLevel extends SewerLevel {
initRooms.add( roomEntrance = new SewerBossEntranceRoom() ); initRooms.add( roomEntrance = new SewerBossEntranceRoom() );
initRooms.add( roomExit = new SewerBossExitRoom() ); initRooms.add( roomExit = new SewerBossExitRoom() );
int standards = standardRooms(); int standards = standardRooms(true);
for (int i = 0; i < standards; i++) { for (int i = 0; i < standards; i++) {
StandardRoom s = StandardRoom.createRoom(); StandardRoom s = StandardRoom.createRoom();
//force to normal size //force to normal size
@ -75,7 +75,8 @@ public class SewerBossLevel extends SewerLevel {
} }
@Override @Override
protected int standardRooms() { protected int standardRooms(boolean forceMax) {
if (forceMax) return 3;
//2 to 3, average 2.5 //2 to 3, average 2.5
return 2+Random.chances(new float[]{1, 1}); return 2+Random.chances(new float[]{1, 1});
} }

View File

@ -57,13 +57,15 @@ public class SewerLevel extends RegularLevel {
} }
@Override @Override
protected int standardRooms() { protected int standardRooms(boolean forceMax) {
if (forceMax) return 7;
//5 to 7, average 5.57 //5 to 7, average 5.57
return 5+Random.chances(new float[]{4, 2, 1}); return 5+Random.chances(new float[]{4, 2, 1});
} }
@Override @Override
protected int specialRooms() { protected int specialRooms(boolean forceMax) {
if (forceMax) return 3;
//1 to 3, average 1.67 //1 to 3, average 1.67
return 1+Random.chances(new float[]{4, 4, 2}); return 1+Random.chances(new float[]{4, 4, 2});
} }

View File

@ -165,6 +165,17 @@ public abstract class RegularPainter extends Painter {
} }
protected void paintDoors( Level l, ArrayList<Room> rooms ) { protected void paintDoors( Level l, ArrayList<Room> rooms ) {
float hiddenDoorChance = 0;
if (Dungeon.depth > 1){
//chance for a hidden door scales from 2/20 on floor 2 to 20/20 on floor 20
hiddenDoorChance = Math.min(1f, Dungeon.depth / 20f);
}
if (l.feeling == Level.Feeling.SECRETS){
//pull the value of extra secret doors toward 50% on secrets level feel
hiddenDoorChance = (0.5f + hiddenDoorChance)/2f;
}
for (Room r : rooms) { for (Room r : rooms) {
for (Room n : r.connected.keySet()) { for (Room n : r.connected.keySet()) {
@ -176,13 +187,12 @@ public abstract class RegularPainter extends Painter {
int door = d.x + d.y * l.width(); int door = d.x + d.y * l.width();
if (d.type == Room.Door.Type.REGULAR){ if (d.type == Room.Door.Type.REGULAR){
//chance for a hidden door scales from 3/21 on floor 2 to 3/3 on floor 20 if (Random.Float() < hiddenDoorChance) {
if (Dungeon.depth > 1 &&
(Dungeon.depth >= 20 || Random.Int(23 - Dungeon.depth) < Dungeon.depth)) {
d.type = Room.Door.Type.HIDDEN; d.type = Room.Door.Type.HIDDEN;
Graph.buildDistanceMap(rooms, r); Graph.buildDistanceMap(rooms, r);
//don't hide if it would make this room only accessible by hidden doors //don't hide if it would make this room only accessible by hidden doors
if (n.distance == Integer.MAX_VALUE){ //unless we're on a secrets depth
if (l.feeling != Level.Feeling.SECRETS && n.distance == Integer.MAX_VALUE){
d.type = Room.Door.Type.UNLOCKED; d.type = Room.Door.Type.UNLOCKED;
} }
} else { } else {
@ -371,6 +381,20 @@ public abstract class RegularPainter extends Painter {
//some traps will not be hidden //some traps will not be hidden
l.map[trapPos] = trap.visible ? Terrain.TRAP : Terrain.SECRET_TRAP; l.map[trapPos] = trap.visible ? Terrain.TRAP : Terrain.SECRET_TRAP;
} }
//4x regular trap count of visible traps on traps level feeling
if (l.feeling == Level.Feeling.TRAPS){
for (int i = 0; i < 4*nTraps; i++) {
Integer trapPos = Random.element(validCells);
validCells.remove(trapPos); //removes the integer object, not at the index
Trap trap = Reflection.newInstance(trapClasses[Random.chances( trapChances )]).reveal();
l.setTrap( trap, trapPos );
//some traps will not be hidden
l.map[trapPos] = trap.visible ? Terrain.TRAP : Terrain.SECRET_TRAP;
}
}
} }
} }

View File

@ -484,19 +484,13 @@ public class GameScene extends PixelScene {
} }
switch (Dungeon.level.feeling) { switch (Dungeon.level.feeling) {
case CHASM: case CHASM: GLog.w(Messages.get(this, "chasm")); break;
GLog.w(Messages.get(this, "chasm")); case WATER: GLog.w(Messages.get(this, "water")); break;
break; case GRASS: GLog.w(Messages.get(this, "grass")); break;
case WATER: case DARK: GLog.w(Messages.get(this, "dark")); break;
GLog.w(Messages.get(this, "water")); case LARGE: GLog.w(Messages.get(this, "large")); break;
break; case TRAPS: GLog.w(Messages.get(this, "traps")); break;
case GRASS: case SECRETS: GLog.w(Messages.get(this, "secrets")); break;
GLog.w(Messages.get(this, "grass"));
break;
case DARK:
GLog.w(Messages.get(this, "dark"));
break;
default:
} }
for (Mob mob : Dungeon.level.mobs) { for (Mob mob : Dungeon.level.mobs) {