From 575357fb324f77bbbc4ab02b57fd698ec69c51c4 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Wed, 7 Jun 2023 21:52:29 -0400 Subject: [PATCH] v2.1.1: added lots of new code to support actually using depth branches --- .../shatteredpixeldungeon/Dungeon.java | 62 ++++++++++++++----- .../actors/hero/Hero.java | 4 +- .../levels/DeadEndLevel.java | 14 ++++- .../shatteredpixeldungeon/levels/Level.java | 5 +- .../levels/features/LevelTransition.java | 4 +- .../scenes/InterlevelScene.java | 40 +++++++----- 6 files changed, 94 insertions(+), 35 deletions(-) diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java index 9fced04b1..b53a2745c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java @@ -179,9 +179,12 @@ public class Dungeon { public static int depth; //determines path the hero is on. Current uses: // 0 is the default path - // Other numbers are currently unused + // 1 is for quest sub-floors public static int branch; + //keeps track of what levels the game should try to load instead of creating fresh + public static ArrayList generatedLevels = new ArrayList<>(); + public static int gold; public static int energy; @@ -244,6 +247,7 @@ public class Dungeon { depth = 1; branch = 0; + generatedLevels.clear(); gold = 0; energy = 0; @@ -270,21 +274,15 @@ public class Dungeon { public static boolean isChallenged( int mask ) { return (challenges & mask) != 0; } + + public static boolean levelHasBeenGenerated(int depth, int branch){ + return generatedLevels.contains(depth + 1000*branch); + } public static Level newLevel() { Dungeon.level = null; Actor.clear(); - - if (depth > Statistics.deepestFloor) { - Statistics.deepestFloor = depth; - - if (Statistics.qualifiedForNoKilling) { - Statistics.completedWithNoKilling = true; - } else { - Statistics.completedWithNoKilling = false; - } - } Level level; if (branch == 0) { @@ -339,16 +337,33 @@ public class Dungeon { break; default: level = new DeadEndLevel(); - Statistics.deepestFloor--; } } else { level = new DeadEndLevel(); - Statistics.deepestFloor--; + } + + //dead end levels get cleared, don't count as generated + if (!(level instanceof DeadEndLevel)){ + //this assumes that we will never have a depth value outside the range 0 to 999 + // or -500 to 499, etc. + if (!generatedLevels.contains(depth + 1000*branch)) { + generatedLevels.add(depth + 1000 * branch); + } + + if (depth > Statistics.deepestFloor && branch == 0) { + Statistics.deepestFloor = depth; + + if (Statistics.qualifiedForNoKilling) { + Statistics.completedWithNoKilling = true; + } else { + Statistics.completedWithNoKilling = false; + } + } } level.create(); - Statistics.qualifiedForNoKilling = !bossLevel(); + if (branch == 0) Statistics.qualifiedForNoKilling = !bossLevel(); Statistics.qualifiedForBossChallengeBadge = false; return level; @@ -524,6 +539,7 @@ public class Dungeon { private static final String HERO = "hero"; private static final String DEPTH = "depth"; private static final String BRANCH = "branch"; + private static final String GENERATED_LEVELS = "generated_levels"; private static final String GOLD = "gold"; private static final String ENERGY = "energy"; private static final String DROPPED = "dropped%d"; @@ -583,6 +599,12 @@ public class Dungeon { Statistics.storeInBundle( bundle ); Notes.storeInBundle( bundle ); Generator.storeInBundle( bundle ); + + int[] bundleArr = new int[generatedLevels.size()]; + for (int i = 0; i < generatedLevels.size(); i++){ + bundleArr[i] = generatedLevels.get(i); + } + bundle.put( GENERATED_LEVELS, bundleArr); Scroll.save( bundle ); Potion.save( bundle ); @@ -713,6 +735,18 @@ public class Dungeon { Statistics.restoreFromBundle( bundle ); Generator.restoreFromBundle( bundle ); + generatedLevels.clear(); + if (bundle.contains(GENERATED_LEVELS)){ + for (int i : bundle.getIntArray(GENERATED_LEVELS)){ + generatedLevels.add(i); + } + //pre-v2.1.1 saves + } else { + for (int i = 1; i <= Statistics.deepestFloor; i++){ + generatedLevels.add(i); + } + } + droppedItems = new SparseArray<>(); for (int i=1; i <= 26; i++) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java index cb91e7d68..2a794041c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java @@ -1194,8 +1194,8 @@ public class Hero extends Char { Level.beforeTransition(); InterlevelScene.curTransition = transition; - //TODO probably want to make this more flexible when more types exist - if (transition.type == LevelTransition.Type.REGULAR_EXIT) { + if (transition.type == LevelTransition.Type.REGULAR_EXIT + || transition.type == LevelTransition.Type.BRANCH_EXIT) { InterlevelScene.mode = InterlevelScene.Mode.DESCEND; } else { InterlevelScene.mode = InterlevelScene.Mode.ASCEND; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/DeadEndLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/DeadEndLevel.java index b1b363180..8758cbe5a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/DeadEndLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/DeadEndLevel.java @@ -22,6 +22,7 @@ package com.shatteredpixel.shatteredpixeldungeon.levels; import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; @@ -66,7 +67,18 @@ public class DeadEndLevel extends Level { } int entrance = SIZE * width() + SIZE / 2 + 1; - transitions.add(new LevelTransition(this, entrance, LevelTransition.Type.REGULAR_ENTRANCE)); + + //different exit behaviour depending on main branch or side one + if (Dungeon.branch == 0) { + transitions.add(new LevelTransition(this, entrance, LevelTransition.Type.REGULAR_ENTRANCE)); + } else { + transitions.add(new LevelTransition(this, + entrance, + LevelTransition.Type.BRANCH_ENTRANCE, + Dungeon.depth, + 0, + LevelTransition.Type.BRANCH_EXIT)); + } map[entrance] = Terrain.ENTRANCE; return true; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java index 36841c21d..9a4235c8f 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java @@ -186,8 +186,9 @@ public abstract class Level implements Bundlable { public void create() { Random.pushGenerator( Dungeon.seedCurDepth() ); - - if (!(Dungeon.bossLevel())) { + + //TODO maybe just make this part of RegularLevel? + if (!Dungeon.bossLevel() && Dungeon.branch == 0) { addItemToSpawn(Generator.random(Generator.Category.FOOD)); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/features/LevelTransition.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/features/LevelTransition.java index c6e894b9c..883cd0f5d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/features/LevelTransition.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/features/LevelTransition.java @@ -34,7 +34,9 @@ public class LevelTransition extends Rect implements Bundlable { public enum Type { SURFACE, REGULAR_ENTRANCE, - REGULAR_EXIT; + REGULAR_EXIT, + BRANCH_ENTRANCE, + BRANCH_EXIT; } public Type type; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java index 8a5913ea0..fc41638a1 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/InterlevelScene.java @@ -384,11 +384,11 @@ public class InterlevelScene extends PixelScene { Level level; Dungeon.depth = curTransition.destDepth; Dungeon.branch = curTransition.destBranch; - //TODO this is brittle atm, assumes we're always going down in depth 1 at a time - if (curTransition.destDepth > Statistics.deepestFloor) { - level = Dungeon.newLevel(); - } else { + + if (Dungeon.levelHasBeenGenerated(Dungeon.depth, Dungeon.branch)) { level = Dungeon.loadLevel( GamesInProgress.curSlot ); + } else { + level = Dungeon.newLevel(); } LevelTransition destTransition = level.getTransition(curTransition.destType); @@ -408,22 +408,27 @@ public class InterlevelScene extends PixelScene { Level level; Dungeon.depth++; - if (Dungeon.depth > Statistics.deepestFloor) { - level = Dungeon.newLevel(); - } else { + if (Dungeon.levelHasBeenGenerated(Dungeon.depth, Dungeon.branch)) { level = Dungeon.loadLevel( GamesInProgress.curSlot ); + } else { + level = Dungeon.newLevel(); } Dungeon.switchLevel( level, level.fallCell( fallIntoPit )); } - - private void ascend() throws IOException { - - Mob.holdAllies( Dungeon.level ); + private void ascend() throws IOException { + Mob.holdAllies( Dungeon.level ); Dungeon.saveAll(); + + Level level; Dungeon.depth = curTransition.destDepth; Dungeon.branch = curTransition.destBranch; - Level level = Dungeon.loadLevel( GamesInProgress.curSlot ); + + if (Dungeon.levelHasBeenGenerated(Dungeon.depth, Dungeon.branch)) { + level = Dungeon.loadLevel( GamesInProgress.curSlot ); + } else { + level = Dungeon.newLevel(); + } LevelTransition destTransition = level.getTransition(curTransition.destType); curTransition = null; @@ -431,13 +436,18 @@ public class InterlevelScene extends PixelScene { } private void returnTo() throws IOException { - Mob.holdAllies( Dungeon.level ); - Dungeon.saveAll(); + + Level level; Dungeon.depth = returnDepth; Dungeon.branch = returnBranch; - Level level = Dungeon.loadLevel( GamesInProgress.curSlot ); + if (Dungeon.levelHasBeenGenerated(Dungeon.depth, Dungeon.branch)) { + level = Dungeon.loadLevel( GamesInProgress.curSlot ); + } else { + level = Dungeon.newLevel(); + } + Dungeon.switchLevel( level, returnPos ); }