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.water=You hear water splashing around you.
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.choose_examine=Choose 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
protected int standardRooms() {
protected int standardRooms(boolean forceMax) {
if (forceMax) return 9;
//6 to 9, average 7.333
return 6+Random.chances(new float[]{2, 3, 3, 1});
}
@Override
protected int specialRooms() {
protected int specialRooms(boolean forceMax) {
if (forceMax) return 3;
//1 to 3, average 2.2
return 1+Random.chances(new float[]{2, 4, 4});
}

View File

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

View File

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

View File

@ -101,7 +101,10 @@ public abstract class Level implements Bundlable {
CHASM,
WATER,
GRASS,
DARK
DARK,
LARGE,
TRAPS,
SECRETS
}
protected int width;
@ -209,23 +212,33 @@ public abstract class Level implements Bundlable {
}
if (Dungeon.depth > 1) {
switch (Random.Int( 10 )) {
case 0:
if (!Dungeon.bossLevel( Dungeon.depth + 1 )) {
//50% chance of getting a level feeling
//~7.15% chance for each feeling
switch (Random.Int( 14 )) {
case 0:
feeling = Feeling.CHASM;
}
break;
case 1:
feeling = Feeling.WATER;
break;
case 2:
feeling = Feeling.GRASS;
break;
case 3:
feeling = Feeling.DARK;
addItemToSpawn(new Torch());
viewDistance = Math.round(viewDistance/2f);
break;
break;
case 1:
feeling = Feeling.WATER;
break;
case 2:
feeling = Feeling.GRASS;
break;
case 3:
feeling = Feeling.DARK;
addItemToSpawn(new Torch());
viewDistance = Math.round(viewDistance/2f);
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.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Wandmaker;
import com.watabou.noosa.Halo;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.FlameParticle;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
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.tiles.DungeonTilemap;
import com.watabou.noosa.Group;
import com.watabou.noosa.Halo;
import com.watabou.noosa.particles.Emitter;
import com.watabou.utils.PointF;
import com.watabou.utils.Random;
@ -63,13 +63,15 @@ public class PrisonLevel extends RegularLevel {
}
@Override
protected int standardRooms() {
protected int standardRooms(boolean forceMax) {
if (forceMax) return 8;
//6 to 8, average 6.66
return 6+Random.chances(new float[]{4, 2, 2});
}
@Override
protected int specialRooms() {
protected int specialRooms(boolean forceMax) {
if (forceMax) return 3;
//1 to 3, average 1.83
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<>();
initRooms.add ( roomEntrance = new EntranceRoom());
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++) {
StandardRoom s;
do {
@ -108,8 +112,12 @@ public abstract class RegularLevel extends Level {
if (Dungeon.shopOnLevel())
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();
for (int i = 0; i < specials; i++) {
SpecialRoom s = SpecialRoom.createRoom();
@ -118,17 +126,20 @@ public abstract class RegularLevel extends Level {
}
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());
}
return initRooms;
}
protected int standardRooms(){
protected int standardRooms(boolean forceMax){
return 0;
}
protected int specialRooms(){
protected int specialRooms(boolean forceMax){
return 0;
}
@ -155,13 +166,13 @@ public abstract class RegularLevel extends Level {
@Override
public int nMobs() {
switch(Dungeon.depth) {
case 1:
//mobs are not randomly spawned on floor 1.
return 0;
default:
return 3 + Dungeon.depth % 5 + Random.Int(3);
if (Dungeon.depth <= 1) return 0;
int mobs = 3 + Dungeon.depth % 5 + Random.Int(3);
if (feeling == Feeling.LARGE){
mobs = (int)Math.ceil(mobs * 1.33f);
}
return mobs;
}
@Override
@ -288,6 +299,10 @@ public abstract class RegularLevel extends Level {
// drops 3/4/5 items 60%/30%/10% of the time
int nItems = 3 + Random.chances(new float[]{6, 3, 1});
if (feeling == Feeling.LARGE){
nItems += 2;
}
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( roomExit = new SewerBossExitRoom() );
int standards = standardRooms();
int standards = standardRooms(true);
for (int i = 0; i < standards; i++) {
StandardRoom s = StandardRoom.createRoom();
//force to normal size
@ -75,7 +75,8 @@ public class SewerBossLevel extends SewerLevel {
}
@Override
protected int standardRooms() {
protected int standardRooms(boolean forceMax) {
if (forceMax) return 3;
//2 to 3, average 2.5
return 2+Random.chances(new float[]{1, 1});
}

View File

@ -57,13 +57,15 @@ public class SewerLevel extends RegularLevel {
}
@Override
protected int standardRooms() {
protected int standardRooms(boolean forceMax) {
if (forceMax) return 7;
//5 to 7, average 5.57
return 5+Random.chances(new float[]{4, 2, 1});
}
@Override
protected int specialRooms() {
protected int specialRooms(boolean forceMax) {
if (forceMax) return 3;
//1 to 3, average 1.67
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 ) {
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 n : r.connected.keySet()) {
@ -176,13 +187,12 @@ public abstract class RegularPainter extends Painter {
int door = d.x + d.y * l.width();
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 (Dungeon.depth > 1 &&
(Dungeon.depth >= 20 || Random.Int(23 - Dungeon.depth) < Dungeon.depth)) {
if (Random.Float() < hiddenDoorChance) {
d.type = Room.Door.Type.HIDDEN;
Graph.buildDistanceMap(rooms, r);
//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;
}
} else {
@ -371,6 +381,20 @@ public abstract class RegularPainter extends Painter {
//some traps will not be hidden
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) {
case CHASM:
GLog.w(Messages.get(this, "chasm"));
break;
case WATER:
GLog.w(Messages.get(this, "water"));
break;
case GRASS:
GLog.w(Messages.get(this, "grass"));
break;
case DARK:
GLog.w(Messages.get(this, "dark"));
break;
default:
case CHASM: GLog.w(Messages.get(this, "chasm")); break;
case WATER: GLog.w(Messages.get(this, "water")); break;
case GRASS: GLog.w(Messages.get(this, "grass")); break;
case DARK: GLog.w(Messages.get(this, "dark")); break;
case LARGE: GLog.w(Messages.get(this, "large")); break;
case TRAPS: GLog.w(Messages.get(this, "traps")); break;
case SECRETS: GLog.w(Messages.get(this, "secrets")); break;
}
for (Mob mob : Dungeon.level.mobs) {