From e159913b686a8bad06edd58b6a14ffbfd991c5c8 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Fri, 21 Nov 2025 15:43:47 -0500 Subject: [PATCH] v3.3.0: expanded vault level a bit with some initial rough layout --- .../shatteredpixeldungeon/Dungeon.java | 4 +- .../actors/hero/Belongings.java | 1 - .../items/quest/EscapeCrystal.java | 2 +- .../levels/CityLevel.java | 10 +- .../levels/VaultLevel.java | 177 +++++++++++++++++- 5 files changed, 183 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java index fee58d1c9..bd9d27aa9 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java @@ -374,8 +374,8 @@ public class Dungeon { level = new DeadEndLevel(); } - //dead end levels get cleared, don't count as generated - if (!(level instanceof DeadEndLevel)){ + //dead end levels (and vault levels for now!) get cleared, don't count as generated + if (!(level instanceof DeadEndLevel || level instanceof VaultLevel)){ //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)) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Belongings.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Belongings.java index 16fd80468..933d8a734 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Belongings.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Belongings.java @@ -214,7 +214,6 @@ public class Belongings implements Iterable { } public void clear(){ - //TODO probably more needed here, what about buffs from these items? e.g. chargers backpack.clear(); weapon = secondWep = null; armor = null; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/EscapeCrystal.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/EscapeCrystal.java index 37c3032c9..153208873 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/EscapeCrystal.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/EscapeCrystal.java @@ -93,9 +93,9 @@ public class EscapeCrystal extends Item { LevelTransition.Type.BRANCH_EXIT); InterlevelScene.mode = InterlevelScene.Mode.ASCEND; Game.switchScene( InterlevelScene.class ); + detach(hero.belongings.backpack); } - detach(hero.belongings.backpack); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CityLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CityLevel.java index 0b0f85de2..362a66202 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CityLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/CityLevel.java @@ -166,9 +166,13 @@ public class CityLevel extends RegularLevel { } } - EscapeCrystal crystal = new EscapeCrystal(); - crystal.storeHeroBelongings(Dungeon.hero); - crystal.collect(); + //not ideal handler for a crash, should improve this + EscapeCrystal crystal = hero.belongings.getItem(EscapeCrystal.class); + if (crystal == null) { + crystal = new EscapeCrystal(); + crystal.storeHeroBelongings(Dungeon.hero); + crystal.collect(); + } Dungeon.hero.belongings.armor = new ClothArmor(); Dungeon.hero.belongings.armor.identify(); CityLevel.super.activateTransition(hero, transition); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/VaultLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/VaultLevel.java index 21576dcff..56674860f 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/VaultLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/VaultLevel.java @@ -22,10 +22,29 @@ package com.shatteredpixel.shatteredpixeldungeon.levels; import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Bones; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; +import com.shatteredpixel.shatteredpixeldungeon.items.Generator; +import com.shatteredpixel.shatteredpixeldungeon.items.Heap; +import com.shatteredpixel.shatteredpixeldungeon.items.Item; +import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfMagicMapping; import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition; +import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.RegionDecoLineRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.SegmentedRoom; +import com.watabou.utils.Point; +import com.watabou.utils.Random; +import com.watabou.utils.Rect; -public class VaultLevel extends DeadEndLevel { //for now +import java.util.ArrayList; + +public class VaultLevel extends Level { //for now { color1 = 0x4b6636; @@ -44,10 +63,130 @@ public class VaultLevel extends DeadEndLevel { //for now @Override protected boolean build() { - super.build(); + setSize(34, 34); + + ArrayList rooms = new ArrayList<>(); + + Room finalRoom = null; + Room entryRoom = null; + + for (int x = 0; x < 4; x++){ + for (int y = 0; y < 4; y++){ + + if (x == 3 && y <= 1){ + if (y == 1) { + continue; + } else { + Room r = new RegionDecoLineRoom(); + r.set(1+8*x, 1+8*y, 9+8*x, 17); + rooms.add(r); + finalRoom = r; + continue; + } + } + Room r = new SegmentedRoom(); + r.set(1+8*x, 1+8*y, 9+8*x, 9+8*y); + rooms.add(r); + + if (x == 0 && y == 3){ + entryRoom = r; + } + } + } + + //builder.findneighbnours + Room[] ra = rooms.toArray( new Room[0] ); + for (int i=0; i < ra.length-1; i++) { + for (int j=i+1; j < ra.length; j++) { + ra[i].addNeigbour( ra[j] ); + } + } + + for (Room n : rooms){ + for (Room p : rooms){ + if (p.height() > 10){ + continue; + } + if (n.height() > 10){ + if (n.canConnect(p)){ + if (n.bottom == p.top){ + n.connect(p); + } + } + } else if (n.canConnect(p)) { + n.connect(p); + } + } + } + + //Painter.placedoors + for (Room r : rooms){ + for (Room n : r.connected.keySet()) { + Room.Door door = r.connected.get( n ); + if (door == null) { + + Rect i = r.intersect( n ); + ArrayList doorSpots = new ArrayList<>(); + for (Point p : i.getPoints()){ + if (r.canConnect(p) && n.canConnect(p)) + doorSpots.add(p); + } + if (doorSpots.isEmpty()){ + ShatteredPixelDungeon.reportException( + new RuntimeException("Could not place a door! " + + "r=" + r.getClass().getSimpleName() + + " n=" + n.getClass().getSimpleName())); + continue; + } + door = new Room.Door(Random.element(doorSpots)); + + r.connected.put( n, door ); + n.connected.put( r, door ); + } + } + } + + for (Room n : rooms){ + n.paint(this); + if (n instanceof RegionDecoLineRoom){ + Painter.fill(this, n, 1, Terrain.EMPTY_SP); + Painter.fill(this, n.left+1, n.top+1, 7, 1, Terrain.REGION_DECO_ALT); + Painter.fill(this, n.left+1, n.top+1, 1, 14, Terrain.REGION_DECO_ALT); + Painter.fill(this, n.right-1, n.top+1, 1, 14, Terrain.REGION_DECO_ALT); + } + for (Point door : n.connected.values()){ + Level.set(pointToCell(door), Terrain.DOOR, this); + } + } + + entrance = pointToCell(entryRoom.random()); + transitions.add(new LevelTransition(this, + entrance, + LevelTransition.Type.BRANCH_ENTRANCE, + Dungeon.depth, + 0, + LevelTransition.Type.BRANCH_EXIT)); + drop(new ScrollOfMagicMapping(), pointToCell(entryRoom.random())); + + rooms.remove(entryRoom); + rooms.remove(finalRoom); + + for (Room n : rooms){ + if (Random.Int(5) != 0){ + Item item = Generator.randomUsingDefaults(Random.oneOf( + Generator.Category.WEAPON, Generator.Category.WEAPON, + Generator.Category.ARMOR, + Generator.Category.WAND, + Generator.Category.RING)); + int pos; + do { + pos = pointToCell(n.random()); + } while (map[pos] != Terrain.EMPTY); + item.identify(); + drop(item, pos); + } + } - int entrance = 5 * width() + 5 / 2 + 1; - map[entrance] = Terrain.WATER; //override entrance tile return true; } @@ -56,4 +195,34 @@ public class VaultLevel extends DeadEndLevel { //for now //walking onto transitions does nothing, need to use crystal return false; } + + @Override + public Mob createMob() { + return null; + } + + @Override + protected void createMobs() { + } + + public Actor addRespawner() { + return null; + } + + @Override + protected void createItems() { + Random.pushGenerator(Random.Long()); + ArrayList bonesItems = Bones.get(); + if (bonesItems != null) { + for (Item i : bonesItems) { + drop(i, entrance()-width()).setHauntedIfCursed().type = Heap.Type.REMAINS; + } + } + Random.popGenerator(); + } + + @Override + public int randomRespawnCell( Char ch ) { + return entrance()-width(); + } }