v2.2.0: fixed into darkness challenge affecting broader levelgen

This commit is contained in:
Evan Debenham
2023-10-11 14:06:22 -04:00
parent e5e6d73b19
commit a6d7116d38
2 changed files with 152 additions and 131 deletions

View File

@@ -195,10 +195,6 @@ public abstract class Level implements Bundlable {
addItemToSpawn(Generator.random(Generator.Category.FOOD));
if (Dungeon.isChallenged(Challenges.DARKNESS)){
addItemToSpawn( new Torch() );
}
if (Dungeon.posNeeded()) {
addItemToSpawn( new PotionOfStrength() );
Dungeon.LimitedDrops.STRENGTH_POTIONS.count++;
@@ -243,10 +239,6 @@ public abstract class Level implements Bundlable {
case 4:
feeling = Feeling.LARGE;
addItemToSpawn(Generator.random(Generator.Category.FOOD));
//add a second torch to help with the larger floor
if (Dungeon.isChallenged(Challenges.DARKNESS)){
addItemToSpawn( new Torch() );
}
break;
case 5:
feeling = Feeling.TRAPS;

View File

@@ -22,6 +22,7 @@
package com.shatteredpixel.shatteredpixeldungeon.levels;
import com.shatteredpixel.shatteredpixeldungeon.Bones;
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
@@ -38,6 +39,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Ghost;
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.Torch;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.Artifact;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
import com.shatteredpixel.shatteredpixeldungeon.items.food.SmallRation;
@@ -411,151 +413,178 @@ public abstract class RegularLevel extends Level {
}
}
//use a separate generator for this to prevent held items, meta progress, and talents from affecting levelgen
//we can use a random long for the seed as it will be the same long every time
//use separate generator(s) for this to prevent held items, meta progress, and talents from affecting levelgen
//we can use a random long for these as they will be the same longs every time
Random.pushGenerator( Random.Long() );
Item item = Bones.get();
if (item != null) {
int cell = randomDropCell();
if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) {
map[cell] = Terrain.GRASS;
losBlocking[cell] = false;
}
drop( item, cell ).setHauntedIfCursed().type = Heap.Type.REMAINS;
}
DriedRose rose = Dungeon.hero.belongings.getItem( DriedRose.class );
if (rose != null && rose.isIdentified() && !rose.cursed && Ghost.Quest.completed()){
//aim to drop 1 petal every 2 floors
int petalsNeeded = (int) Math.ceil((float)((Dungeon.depth / 2) - rose.droppedPetals) / 3);
for (int i=1; i <= petalsNeeded; i++) {
//the player may miss a single petal and still max their rose.
if (rose.droppedPetals < 11) {
item = new DriedRose.Petal();
int cell = randomDropCell();
drop( item, cell ).type = Heap.Type.HEAP;
if (Dungeon.isChallenged(Challenges.DARKNESS)){
int cell = randomDropCell();
if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) {
map[cell] = Terrain.GRASS;
losBlocking[cell] = false;
}
drop( new Torch(), cell );
//add a second torch to help with the larger floor
if (feeling == Feeling.LARGE){
cell = randomDropCell();
if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) {
map[cell] = Terrain.GRASS;
losBlocking[cell] = false;
}
rose.droppedPetals++;
drop( new Torch(), cell );
}
}
}
Random.popGenerator();
//cached rations try to drop in a special room on floors 2/3/4/6/7/8, to a max of 4/6
if (Dungeon.hero.hasTalent(Talent.CACHED_RATIONS)){
Talent.CachedRationsDropped dropped = Buff.affect(Dungeon.hero, Talent.CachedRationsDropped.class);
if (dropped.count() < 2 + 2*Dungeon.hero.pointsInTalent(Talent.CACHED_RATIONS)){
int cell;
int tries = 100;
boolean valid;
do {
cell = randomDropCell(SpecialRoom.class);
valid = cell != -1 && !(room(cell) instanceof SecretRoom)
&& !(room(cell) instanceof ShopRoom)
&& map[cell] != Terrain.EMPTY_SP
&& map[cell] != Terrain.WATER
&& map[cell] != Terrain.PEDESTAL;
} while (tries-- > 0 && !valid);
if (valid) {
if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) {
map[cell] = Terrain.GRASS;
losBlocking[cell] = false;
}
drop(new SmallRation(), cell).type = Heap.Type.CHEST;
dropped.countUp(1);
Random.pushGenerator( Random.Long() );
Item item = Bones.get();
if (item != null) {
int cell = randomDropCell();
if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) {
map[cell] = Terrain.GRASS;
losBlocking[cell] = false;
}
drop( item, cell ).setHauntedIfCursed().type = Heap.Type.REMAINS;
}
}
Random.popGenerator();
//guide pages
Collection<String> allPages = Document.ADVENTURERS_GUIDE.pageNames();
ArrayList<String> missingPages = new ArrayList<>();
for ( String page : allPages){
if (!Document.ADVENTURERS_GUIDE.isPageFound(page)){
missingPages.add(page);
}
}
Random.pushGenerator( Random.Long() );
DriedRose rose = Dungeon.hero.belongings.getItem( DriedRose.class );
if (rose != null && rose.isIdentified() && !rose.cursed && Ghost.Quest.completed()){
//aim to drop 1 petal every 2 floors
int petalsNeeded = (int) Math.ceil((float)((Dungeon.depth / 2) - rose.droppedPetals) / 3);
//a total of 6 pages drop randomly, the rest are specially dropped or are given at the start
missingPages.remove(Document.GUIDE_SEARCHING);
//chance to find a page is 0/25/50/75/100% for floors 1/2/3/4/5+
float dropChance = 0.25f*(Dungeon.depth-1);
if (!missingPages.isEmpty() && Random.Float() < dropChance){
GuidePage p = new GuidePage();
p.page(missingPages.get(0));
int cell = randomDropCell();
if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) {
map[cell] = Terrain.GRASS;
losBlocking[cell] = false;
}
drop( p, cell );
}
//lore pages
//TODO a fair bit going on here, I might want to refactor/externalize this in the future
if (Document.ADVENTURERS_GUIDE.allPagesFound()){
int region = 1+(Dungeon.depth-1)/5;
Document regionDoc;
switch( region ){
default: regionDoc = null; break;
case 1: regionDoc = Document.SEWERS_GUARD; break;
case 2: regionDoc = Document.PRISON_WARDEN; break;
case 3: regionDoc = Document.CAVES_EXPLORER; break;
case 4: regionDoc = Document.CITY_WARLOCK; break;
case 5: regionDoc = Document.HALLS_KING; break;
}
if (regionDoc != null && !regionDoc.allPagesFound()) {
Dungeon.LimitedDrops limit = limitedDocs.get(regionDoc);
if (limit == null || !limit.dropped()) {
float totalPages = 0;
float pagesFound = 0;
String pageToDrop = null;
for (String page : regionDoc.pageNames()) {
totalPages++;
if (!regionDoc.isPageFound(page)) {
if (pageToDrop == null) {
pageToDrop = page;
}
} else {
pagesFound++;
}
}
float percentComplete = pagesFound / totalPages;
// initial value is the first floor in a region
int targetFloor = 5*(region-1) + 1;
targetFloor += Math.round(3*percentComplete);
//TODO maybe drop last page in boss floor with custom logic?
if (Dungeon.depth >= targetFloor){
DocumentPage page = RegionLorePage.pageForDoc(regionDoc);
page.page(pageToDrop);
for (int i=1; i <= petalsNeeded; i++) {
//the player may miss a single petal and still max their rose.
if (rose.droppedPetals < 11) {
item = new DriedRose.Petal();
int cell = randomDropCell();
drop( item, cell ).type = Heap.Type.HEAP;
if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) {
map[cell] = Terrain.GRASS;
losBlocking[cell] = false;
}
drop(page, cell);
if (limit != null) limit.drop();
rose.droppedPetals++;
}
}
}
Random.popGenerator();
//cached rations try to drop in a special room on floors 2/3/4/6/7/8, to a max of 4/6
Random.pushGenerator( Random.Long() );
if (Dungeon.hero.hasTalent(Talent.CACHED_RATIONS)){
Talent.CachedRationsDropped dropped = Buff.affect(Dungeon.hero, Talent.CachedRationsDropped.class);
if (dropped.count() < 2 + 2*Dungeon.hero.pointsInTalent(Talent.CACHED_RATIONS)){
int cell;
int tries = 100;
boolean valid;
do {
cell = randomDropCell(SpecialRoom.class);
valid = cell != -1 && !(room(cell) instanceof SecretRoom)
&& !(room(cell) instanceof ShopRoom)
&& map[cell] != Terrain.EMPTY_SP
&& map[cell] != Terrain.WATER
&& map[cell] != Terrain.PEDESTAL;
} while (tries-- > 0 && !valid);
if (valid) {
if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) {
map[cell] = Terrain.GRASS;
losBlocking[cell] = false;
}
drop(new SmallRation(), cell).type = Heap.Type.CHEST;
dropped.countUp(1);
}
}
}
Random.popGenerator();
//guide pages
Random.pushGenerator( Random.Long() );
Collection<String> allPages = Document.ADVENTURERS_GUIDE.pageNames();
ArrayList<String> missingPages = new ArrayList<>();
for ( String page : allPages){
if (!Document.ADVENTURERS_GUIDE.isPageFound(page)){
missingPages.add(page);
}
}
//a total of 6 pages drop randomly, the rest are specially dropped or are given at the start
missingPages.remove(Document.GUIDE_SEARCHING);
//chance to find a page is 0/25/50/75/100% for floors 1/2/3/4/5+
float dropChance = 0.25f*(Dungeon.depth-1);
if (!missingPages.isEmpty() && Random.Float() < dropChance){
GuidePage p = new GuidePage();
p.page(missingPages.get(0));
int cell = randomDropCell();
if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) {
map[cell] = Terrain.GRASS;
losBlocking[cell] = false;
}
drop( p, cell );
}
Random.popGenerator();
//lore pages
//TODO a fair bit going on here, I might want to refactor/externalize this in the future
Random.pushGenerator( Random.Long() );
if (Document.ADVENTURERS_GUIDE.allPagesFound()){
int region = 1+(Dungeon.depth-1)/5;
Document regionDoc;
switch( region ){
default: regionDoc = null; break;
case 1: regionDoc = Document.SEWERS_GUARD; break;
case 2: regionDoc = Document.PRISON_WARDEN; break;
case 3: regionDoc = Document.CAVES_EXPLORER; break;
case 4: regionDoc = Document.CITY_WARLOCK; break;
case 5: regionDoc = Document.HALLS_KING; break;
}
if (regionDoc != null && !regionDoc.allPagesFound()) {
Dungeon.LimitedDrops limit = limitedDocs.get(regionDoc);
if (limit == null || !limit.dropped()) {
float totalPages = 0;
float pagesFound = 0;
String pageToDrop = null;
for (String page : regionDoc.pageNames()) {
totalPages++;
if (!regionDoc.isPageFound(page)) {
if (pageToDrop == null) {
pageToDrop = page;
}
} else {
pagesFound++;
}
}
float percentComplete = pagesFound / totalPages;
// initial value is the first floor in a region
int targetFloor = 5*(region-1) + 1;
targetFloor += Math.round(3*percentComplete);
//TODO maybe drop last page in boss floor with custom logic?
if (Dungeon.depth >= targetFloor){
DocumentPage page = RegionLorePage.pageForDoc(regionDoc);
page.page(pageToDrop);
int cell = randomDropCell();
if (map[cell] == Terrain.HIGH_GRASS || map[cell] == Terrain.FURROWED_GRASS) {
map[cell] = Terrain.GRASS;
losBlocking[cell] = false;
}
drop(page, cell);
if (limit != null) limit.drop();
}
}
}
}
}
Random.popGenerator();
}