v0.6.2: fully implemented 5 secret rooms

This commit is contained in:
Evan Debenham 2017-09-07 01:00:44 -04:00
parent 595abdd2c6
commit d4489e6901
8 changed files with 247 additions and 78 deletions

View File

@ -79,7 +79,7 @@ public class RatKingRoom extends SecretRoom {
return; return;
} }
Item prize = new Gold( Random.IntRange( 1, 25 ) ); Item prize = new Gold( Random.IntRange( 10, 25 ) );
level.drop( prize, pos ).type = Heap.Type.CHEST; level.drop( prize, pos ).type = Heap.Type.CHEST;
} }

View File

@ -21,34 +21,34 @@
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.secret; package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.secret;
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Foliage; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Foliage;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfRegrowth; import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfRegrowth;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Patch;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.shatteredpixel.shatteredpixeldungeon.plants.BlandfruitBush; import com.shatteredpixel.shatteredpixeldungeon.plants.Starflower;
import com.shatteredpixel.shatteredpixeldungeon.plants.Sungrass;
import com.watabou.utils.Random; import com.watabou.utils.Random;
//TODO specific implementation
public class SecretGardenRoom extends SecretRoom { public class SecretGardenRoom extends SecretRoom {
public void paint( Level level ) { public void paint( Level level ) {
Painter.fill( level, this, Terrain.WALL ); Painter.fill( level, this, Terrain.WALL );
Painter.fill( level, this, 1, Terrain.HIGH_GRASS ); Painter.fill( level, this, 1, Terrain.GRASS );
Painter.fill( level, this, 2, Terrain.GRASS );
boolean[] grass = Patch.generate(width()-2, height()-2, 0.5f, 0, true);
for (int i=top + 1; i < bottom; i++) {
for (int j=left + 1; j < right; j++) {
if (grass[xyToPatchCoords(j, i)]) {
level.map[i * level.width() + j] = Terrain.HIGH_GRASS;
}
}
}
entrance().set( Door.Type.HIDDEN ); entrance().set( Door.Type.HIDDEN );
if (Dungeon.isChallenged(Challenges.NO_FOOD)) { level.plant(new Starflower.Seed(), plantPos(level));
level.plant(new Sungrass.Seed(), plantPos(level));
} else {
level.plant(new BlandfruitBush.Seed(), plantPos(level));
}
level.plant(new WandOfRegrowth.Seedpod.Seed(), plantPos( level )); level.plant(new WandOfRegrowth.Seedpod.Seed(), plantPos( level ));
level.plant(new WandOfRegrowth.Dewcatcher.Seed(), plantPos( level )); level.plant(new WandOfRegrowth.Dewcatcher.Seed(), plantPos( level ));
@ -77,4 +77,8 @@ public class SecretGardenRoom extends SecretRoom {
} while (level.plants.get(pos) != null); } while (level.plants.get(pos) != null);
return pos; return pos;
} }
protected int xyToPatchCoords(int x, int y){
return (x-left-1) + ((y-top-1) * (width()-2));
}
} }

View File

@ -21,9 +21,8 @@
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.secret; package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.secret;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Alchemy; import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Alchemy;
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion; import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfExperience; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfExperience;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfFrost; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfFrost;
@ -31,11 +30,9 @@ import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfInvisibility; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfInvisibility;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLevitation; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLevitation;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLiquidFlame; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLiquidFlame;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfMight;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfMindVision; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfMindVision;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfParalyticGas; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfParalyticGas;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfPurity; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfPurity;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfStrength;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfToxicGas; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfToxicGas;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
@ -51,16 +48,14 @@ public class SecretLaboratoryRoom extends SecretRoom {
private static HashMap<Class<? extends Potion>, Float> potionChances = new HashMap<>(); private static HashMap<Class<? extends Potion>, Float> potionChances = new HashMap<>();
static{ static{
potionChances.put(PotionOfHealing.class, 2f); potionChances.put(PotionOfHealing.class, 2f);
potionChances.put(PotionOfExperience.class, 4f); potionChances.put(PotionOfExperience.class, 5f);
potionChances.put(PotionOfToxicGas.class, 1f); potionChances.put(PotionOfToxicGas.class, 1f);
potionChances.put(PotionOfParalyticGas.class, 2f); potionChances.put(PotionOfParalyticGas.class, 3f);
potionChances.put(PotionOfLiquidFlame.class, 1f); potionChances.put(PotionOfLiquidFlame.class, 1f);
potionChances.put(PotionOfLevitation.class, 1f); potionChances.put(PotionOfLevitation.class, 1f);
potionChances.put(PotionOfStrength.class, 0f); potionChances.put(PotionOfMindVision.class, 3f);
potionChances.put(PotionOfMindVision.class, 2f);
potionChances.put(PotionOfPurity.class, 2f); potionChances.put(PotionOfPurity.class, 2f);
potionChances.put(PotionOfInvisibility.class, 1f); potionChances.put(PotionOfInvisibility.class, 1f);
potionChances.put(PotionOfMight.class, 0f);
potionChances.put(PotionOfFrost.class, 1f); potionChances.put(PotionOfFrost.class, 1f);
} }
@ -69,46 +64,33 @@ public class SecretLaboratoryRoom extends SecretRoom {
Painter.fill( level, this, Terrain.WALL ); Painter.fill( level, this, Terrain.WALL );
Painter.fill( level, this, 1, Terrain.EMPTY_SP ); Painter.fill( level, this, 1, Terrain.EMPTY_SP );
Door entrance = entrance(); entrance().set( Door.Type.HIDDEN );
Point pot = null; Point pot = center();
if (entrance.x == left) {
pot = new Point( right-1, Random.Int( 2 ) == 0 ? top + 1 : bottom - 1 );
} else if (entrance.x == right) {
pot = new Point( left+1, Random.Int( 2 ) == 0 ? top + 1 : bottom - 1 );
} else if (entrance.y == top) {
pot = new Point( Random.Int( 2 ) == 0 ? left + 1 : right - 1, bottom-1 );
} else if (entrance.y == bottom) {
pot = new Point( Random.Int( 2 ) == 0 ? left + 1 : right - 1, top+1 );
}
Painter.set( level, pot, Terrain.ALCHEMY ); Painter.set( level, pot, Terrain.ALCHEMY );
Alchemy alchemy = new Alchemy(); Alchemy alchemy = new Alchemy();
alchemy.seed( level, pot.x + level.width() * pot.y, Random.IntRange(40, 75) ); alchemy.seed( level, pot.x + level.width() * pot.y, Random.IntRange(40, 75) );
level.blobs.put( Alchemy.class, alchemy ); level.blobs.put( Alchemy.class, alchemy );
int n = Random.IntRange( 3, 4 ); int n = Random.IntRange( 2, 4 );
HashMap<Class<? extends Potion>, Float> chances = new HashMap<>(potionChances); HashMap<Class<? extends Potion>, Float> chances = new HashMap<>(potionChances);
for (int i=0; i < n; i++) { for (int i=0; i < n; i++) {
int pos; int pos;
do { do {
pos = level.pointToCell(random()); pos = level.pointToCell(random());
} while ( } while (level.map[pos] != Terrain.EMPTY_SP || level.heaps.get( pos ) != null);
level.map[pos] != Terrain.EMPTY_SP ||
level.heaps.get( pos ) != null); try{
level.drop( prize( level ), pos ); Class<?extends Potion> potionCls = Random.chances(chances);
chances.put(potionCls, 0f);
level.drop( potionCls.newInstance(), pos );
} catch (Exception e){
ShatteredPixelDungeon.reportException(e);
}
} }
entrance.set( Door.Type.HIDDEN );
}
private static Item prize(Level level ) {
Item prize = level.findPrizeItem( Potion.class );
if (prize == null)
prize = Generator.random( Generator.Category.POTION );
return prize;
} }
} }

View File

@ -0,0 +1,93 @@
/*
* 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 <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.secret;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.food.Blandfruit;
import com.shatteredpixel.shatteredpixeldungeon.items.food.ChargrilledMeat;
import com.shatteredpixel.shatteredpixeldungeon.items.food.Food;
import com.shatteredpixel.shatteredpixeldungeon.items.food.Pasty;
import com.shatteredpixel.shatteredpixeldungeon.items.food.SmallRation;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.watabou.utils.Point;
import com.watabou.utils.Random;
import java.util.ArrayList;
public class SecretLarderRoom extends SecretRoom {
@Override
public boolean canConnect(Point p) {
//refuses connections from the top
return super.canConnect(p) && p.x > top+1;
}
@Override
public int maxWidth() {
return 8;
}
@Override
public int maxHeight() {
return 8;
}
@Override
public void paint(Level level) {
super.paint(level);
Painter.fill(level, this, 1, Terrain.EMPTY_SP);
int nFood = width()-2;
ArrayList<Item> foodItems = new ArrayList<>();
//generates 900 food value, spread out over 3-6 pieces of food
if (nFood <= 4){
foodItems.add(Random.Int(2) == 0 ? new Blandfruit() : new Pasty());
nFood--;
}
if (nFood == 3 || nFood == 5){
foodItems.add(new Food());
nFood--;
}
while (nFood > 0){
foodItems.add(Random.Int(2) == 0 ? new ChargrilledMeat() : new SmallRation());
nFood--;
}
Random.shuffle(foodItems);
int topLeft = level.pointToCell(new Point(left+1, top+1));
for(int i = 0; i < foodItems.size(); i++){
level.drop( foodItems.get(i), topLeft+i );
Painter.set(level, topLeft+i, Terrain.PEDESTAL);
}
entrance().set(Door.Type.HIDDEN);
}
}

View File

@ -21,57 +21,84 @@
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.secret; package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.secret;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.keys.IronKey;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfIdentify; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfIdentify;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfLullaby;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfMagicMapping;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfMirrorImage;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfPsionicBlast;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRage;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRecharging;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRemoveCurse; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRemoveCurse;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTerror;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.watabou.utils.Random; import com.watabou.utils.Random;
import java.util.HashMap;
//TODO specific implementation //TODO specific implementation
public class SecretLibraryRoom extends SecretRoom { public class SecretLibraryRoom extends SecretRoom {
@Override
public int minWidth() {
return Math.max(7, super.minWidth());
}
@Override
public int minHeight() {
return Math.max(7, super.minHeight());
}
private static HashMap<Class<? extends Scroll>, Float> scrollChances = new HashMap<>();
static{
scrollChances.put( ScrollOfIdentify.class, 1f );
scrollChances.put( ScrollOfTeleportation.class, 1f );
scrollChances.put( ScrollOfRemoveCurse.class, 3f );
scrollChances.put( ScrollOfRecharging.class, 1f );
scrollChances.put( ScrollOfMagicMapping.class, 3f );
scrollChances.put( ScrollOfRage.class, 1f );
scrollChances.put( ScrollOfTerror.class, 2f );
scrollChances.put( ScrollOfLullaby.class, 2f );
scrollChances.put( ScrollOfPsionicBlast.class, 5f );
scrollChances.put( ScrollOfMirrorImage.class, 1f );
}
public void paint( Level level ) { public void paint( Level level ) {
Painter.fill( level, this, Terrain.WALL ); Painter.fill( level, this, Terrain.WALL );
Painter.fill( level, this, 1, Terrain.EMPTY_SP ); Painter.fill( level, this, 1, Terrain.BOOKSHELF );
Painter.fillEllipse(level, this, 2, Terrain.EMPTY_SP);
Door entrance = entrance(); Door entrance = entrance();
if (entrance.x == left || entrance.x == right){
Painter.drawInside(level, this, entrance, (width() - 3) / 2, Terrain.EMPTY_SP);
} else {
Painter.drawInside(level, this, entrance, (height() - 3) / 2, Terrain.EMPTY_SP);
}
entrance.set( Door.Type.HIDDEN );
Painter.fill( level, left + 1, top+1, width() - 2, 1 , Terrain.BOOKSHELF ); int n = Random.IntRange( 2, 4 );
Painter.drawInside(level, this, entrance, 1, Terrain.EMPTY_SP ); HashMap<Class<? extends Scroll>, Float> chances = new HashMap<>(scrollChances);
int n = Random.IntRange( 2, 3 );
for (int i=0; i < n; i++) { for (int i=0; i < n; i++) {
int pos; int pos;
do { do {
pos = level.pointToCell(random()); pos = level.pointToCell(random());
} while (level.map[pos] != Terrain.EMPTY_SP || level.heaps.get( pos ) != null); } while (level.map[pos] != Terrain.EMPTY_SP || level.heaps.get( pos ) != null);
Item item;
if (i == 0) try{
item = Random.Int(2) == 0 ? new ScrollOfIdentify() : new ScrollOfRemoveCurse(); Class<?extends Scroll> scrollCls = Random.chances(chances);
else chances.put(scrollCls, 0f);
item = prize( level ); level.drop( scrollCls.newInstance(), pos );
level.drop( item, pos ); } catch (Exception e){
ShatteredPixelDungeon.reportException(e);
}
} }
entrance.set( Door.Type.HIDDEN );
level.addItemToSpawn( new IronKey( Dungeon.depth ) );
}
private static Item prize( Level level ) {
Item prize = level.findPrizeItem( Scroll.class );
if (prize == null)
prize = Generator.random( Generator.Category.SCROLL );
return prize;
} }
} }

View File

@ -34,7 +34,7 @@ public abstract class SecretRoom extends SpecialRoom {
private static final ArrayList<Class<? extends SecretRoom>> ALL_SECRETS = new ArrayList<>( Arrays.asList( private static final ArrayList<Class<? extends SecretRoom>> ALL_SECRETS = new ArrayList<>( Arrays.asList(
SecretGardenRoom.class, SecretLaboratoryRoom.class, SecretLibraryRoom.class)); SecretGardenRoom.class, SecretLaboratoryRoom.class, SecretLibraryRoom.class, SecretLarderRoom.class, SecretTransmutationRoom.class));
public static ArrayList<Class<? extends SecretRoom>> runSecrets = new ArrayList<>(); public static ArrayList<Class<? extends SecretRoom>> runSecrets = new ArrayList<>();

View File

@ -0,0 +1,62 @@
/*
* 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 <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.secret;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.WaterOfTransmutation;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter;
import com.watabou.utils.Point;
public class SecretTransmutationRoom extends SecretRoom {
@Override
public boolean canConnect(Point p) {
//refuses connections next to corners
return super.canConnect(p) && ((p.x > left+1 && p.x < right-1) || (p.y > top+1 && p.y < bottom-1));
}
public void paint( Level level ) {
Painter.fill( level, this, Terrain.WALL );
Point door = entrance();
Point well;
if (door.x == left){
well = new Point(right-2, door.y);
} else if (door.x == right){
well = new Point(left+2, door.y);
} else if (door.y == top){
well = new Point(door.x, bottom-2);
} else {
well = new Point(door.x, top+2);
}
Painter.fill(level, well.x-1, well.y-1, 3, 3, Terrain.CHASM);
Painter.drawLine(level, door, well, Terrain.EMPTY);
Painter.set( level, well, Terrain.WELL );
WaterOfTransmutation.seed(well.x + level.width() * well.y, 1, WaterOfTransmutation.class, level);
entrance().set( Door.Type.HIDDEN );
}
}

View File

@ -127,6 +127,7 @@ public class DungeonTileSheet {
chasmStitcheable.put( Terrain.EMPTY_DECO, CHASM_FLOOR ); chasmStitcheable.put( Terrain.EMPTY_DECO, CHASM_FLOOR );
chasmStitcheable.put( Terrain.SIGN, CHASM_FLOOR ); chasmStitcheable.put( Terrain.SIGN, CHASM_FLOOR );
chasmStitcheable.put( Terrain.EMPTY_WELL, CHASM_FLOOR ); chasmStitcheable.put( Terrain.EMPTY_WELL, CHASM_FLOOR );
chasmStitcheable.put( Terrain.WELL, CHASM_FLOOR );
chasmStitcheable.put( Terrain.STATUE, CHASM_FLOOR ); chasmStitcheable.put( Terrain.STATUE, CHASM_FLOOR );
chasmStitcheable.put( Terrain.SECRET_TRAP, CHASM_FLOOR ); chasmStitcheable.put( Terrain.SECRET_TRAP, CHASM_FLOOR );
chasmStitcheable.put( Terrain.INACTIVE_TRAP,CHASM_FLOOR ); chasmStitcheable.put( Terrain.INACTIVE_TRAP,CHASM_FLOOR );