From cd7ed99ac01615b7edec754df47876fab33b6e7b Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Wed, 4 Feb 2026 17:39:12 -0500 Subject: [PATCH] v3.3.5: added two more rooms for tester vault enemies to appear in v3.3.5: fixed an exploit where quitting would cancel fury partway --- .../main/java/com/watabou/utils/Random.java | 13 ++- .../assets/messages/actors/actors.properties | 2 +- .../levels/VaultLevel.java | 8 +- .../rooms/quest/vault/VaultRingsRoom.java | 60 ++++++++++++++ .../vault/VaultSimpleEnemyTreasureRoom.java | 81 +++++++++++++++++++ 5 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/vault/VaultRingsRoom.java create mode 100644 core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/vault/VaultSimpleEnemyTreasureRoom.java diff --git a/SPD-classes/src/main/java/com/watabou/utils/Random.java b/SPD-classes/src/main/java/com/watabou/utils/Random.java index 6afd0c3fc..c93f4b29a 100644 --- a/SPD-classes/src/main/java/com/watabou/utils/Random.java +++ b/SPD-classes/src/main/java/com/watabou/utils/Random.java @@ -256,7 +256,18 @@ public class Random { public synchronized static void shuffle( List list){ Collections.shuffle(list, generators.peek()); } - + + public static void shuffle( int[] array ) { + for (int i=0; i < array.length - 1; i++) { + int j = Int( i, array.length ); + if (j != i) { + int t = array[i]; + array[i] = array[j]; + array[j] = t; + } + } + } + public static void shuffle( T[] array ) { for (int i=0; i < array.length - 1; i++) { int j = Int( i, array.length ); diff --git a/core/src/main/assets/messages/actors/actors.properties b/core/src/main/assets/messages/actors/actors.properties index c97f5b452..7e124a00e 100644 --- a/core/src/main/assets/messages/actors/actors.properties +++ b/core/src/main/assets/messages/actors/actors.properties @@ -1790,7 +1790,7 @@ actors.mobs.tormentedspirit.name=tormented spirit actors.mobs.tormentedspirit.desc=Tormented spirits are otherwise good-natured spirits that have been afflicted by a curse. So long as they are cursed they will attack just like a wraith, and are more powerful as well!\n\nIt may be possible to cleanse the curse by using the right item while next to the spirit. If the curse is lifted the spirit will surely be grateful... actors.mobs.tormentedspirit.thank_you=Thank you... -actors.mobs.vaultrat.desc=This rat has some behaviour changes to test out new vault enemy AI:\n_-_ Its movement can be 'heard' through walls\n_-_ It will wander along a pre-set patrol\n_-_ While wandering it has sharply reduced detection range behind the direction it moves in.\n_-_While sleeping its detection range is also reduced\n_-_ When it detects you it will 'investigate' before swapping to hunting. Investigating enemies move toward you but don't attack and are easier to lose behind doors and corners. +actors.mobs.vaultrat.desc=This rat has some behaviour changes to test out new vault enemy AI:\n_-_ Its movement can be 'heard' through walls\n_-_ It will wander along a pre-set patrol\n_-_ While wandering it has sharply reduced detection range behind the direction it moves in.\n_-_ While sleeping its detection range is also reduced\n_-_ When it detects you it will 'investigate' before swapping to hunting. Investigating enemies move toward you but don't attack and are easier to lose behind doors and corners. actors.mobs.warlock.name=dwarf warlock actors.mobs.warlock.bolt_kill=The shadow bolt killed you... 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 6d93228af..fa5db2e9a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/VaultLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/VaultLevel.java @@ -37,11 +37,14 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.features.LevelTransition; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault.VaultCircleRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault.VaultCrossRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault.VaultEnemyCenterRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault.VaultEntranceRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault.VaultFinalRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault.VaultLongRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault.VaultQuadrantsRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault.VaultRingRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault.VaultRingsRoom; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault.VaultSimpleEnemyTreasureRoom; import com.watabou.utils.Random; import java.util.ArrayList; @@ -54,11 +57,14 @@ public class VaultLevel extends CityLevel { initRooms.add(roomEntrance = new VaultEntranceRoom()); - for (int i = 0; i < 4; i++){ + for (int i = 0; i < 2; i++){ initRooms.add(new VaultRingRoom()); initRooms.add(new VaultCircleRoom()); initRooms.add(new VaultCrossRoom()); initRooms.add(new VaultQuadrantsRoom()); + initRooms.add(new VaultEnemyCenterRoom()); + initRooms.add(new VaultRingsRoom()); + initRooms.add(new VaultSimpleEnemyTreasureRoom()); } initRooms.add(new VaultLongRoom()); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/vault/VaultRingsRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/vault/VaultRingsRoom.java new file mode 100644 index 000000000..a8496426b --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/vault/VaultRingsRoom.java @@ -0,0 +1,60 @@ +package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault; + +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.VaultRat; +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; +import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom; +import com.watabou.utils.Point; +import com.watabou.utils.Random; + +public class VaultRingsRoom extends StandardRoom { + + @Override + public float[] sizeCatProbs() { + return new float[]{0, 1, 0}; + } + + @Override + public void paint(Level level) { + Painter.fill( level, this, Terrain.WALL ); + Painter.fill( level, this, 1 , Terrain.EMPTY ); + + Painter.fill(level, left+2, top+2, 3, 3, Terrain.WALL); + Painter.fill(level, right-4, top+2, 3, 3, Terrain.WALL); + Painter.fill(level, left+2, bottom-4, 3, 3, Terrain.WALL); + Painter.fill(level, right-4, bottom-4, 3, 3, Terrain.WALL); + + for (Door door : connected.values()) { + door.set( Door.Type.REGULAR ); + } + + VaultRat rat = new VaultRat(); + do { + rat.pos = level.pointToCell(random(1)); + } while (level.solid[rat.pos]); + rat.state = rat.WANDERING; + level.mobs.add(rat); + + rat.wanderPositions = new int[]{ + level.pointToCell(new Point(left+1, top+1)), + level.pointToCell(new Point(left+1, top+5)), + level.pointToCell(new Point(left+1, top+9)), + level.pointToCell(new Point(left+5, top+1)), + level.pointToCell(new Point(left+5, top+5)), + level.pointToCell(new Point(left+5, top+9)), + level.pointToCell(new Point(left+9, top+1)), + level.pointToCell(new Point(left+9, top+5)), + level.pointToCell(new Point(left+9, top+9)) + }; + Random.shuffle(rat.wanderPositions); + + } + + @Override + public boolean canMerge(Level l, Room other, Point p, int mergeTerrain) { + return false; + } + +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/vault/VaultSimpleEnemyTreasureRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/vault/VaultSimpleEnemyTreasureRoom.java new file mode 100644 index 000000000..f61ad7977 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/quest/vault/VaultSimpleEnemyTreasureRoom.java @@ -0,0 +1,81 @@ +package com.shatteredpixel.shatteredpixeldungeon.levels.rooms.quest.vault; + +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.VaultRat; +import com.shatteredpixel.shatteredpixeldungeon.items.Generator; +import com.shatteredpixel.shatteredpixeldungeon.items.Heap; +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; +import com.shatteredpixel.shatteredpixeldungeon.levels.painters.Painter; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.Room; +import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.standard.StandardRoom; +import com.watabou.utils.Point; +import com.watabou.utils.Random; + +public class VaultSimpleEnemyTreasureRoom extends StandardRoom { + + @Override + public float[] sizeCatProbs() { + return new float[]{0, 1, 0}; + } + + @Override + public void paint(Level level) { + + Painter.fill( level, this, Terrain.WALL ); + Painter.fill( level, this, 1 , Terrain.EMPTY ); + + int ratPos = 0; + int treasurePos = 0; + switch (Random.Int(4)){ + case 0: + Painter.fill(level, left+2, top+2, 6, 6, Terrain.WALL ); + Painter.fill(level, left+3, top+3, 4, 4, Terrain.EMPTY_SP ); + Painter.fill(level, left+4, top+7, 2, 1, Terrain.EMPTY_SP ); + Painter.fill(level, left+7, top+4, 1, 2, Terrain.EMPTY_SP ); + ratPos = level.pointToCell(new Point(left+4, top+4)); + treasurePos = level.pointToCell(new Point(left+3, top+3)); + break; + case 1: + Painter.fill(level, left+3, top+2, 6, 6, Terrain.WALL ); + Painter.fill(level, left+4, top+3, 4, 4, Terrain.EMPTY_SP ); + Painter.fill(level, left+5, top+7, 2, 1, Terrain.EMPTY_SP ); + Painter.fill(level, left+3, top+4, 1, 2, Terrain.EMPTY_SP ); + ratPos = level.pointToCell(new Point(right-4, top+4)); + treasurePos = level.pointToCell(new Point(right-3, top+3)); + break; + case 2: + Painter.fill(level, left+3, top+3, 6, 6, Terrain.WALL ); + Painter.fill(level, left+4, top+4, 4, 4, Terrain.EMPTY_SP ); + Painter.fill(level, left+5, top+3, 2, 1, Terrain.EMPTY_SP ); + Painter.fill(level, left+3, top+5, 1, 2, Terrain.EMPTY_SP ); + ratPos = level.pointToCell(new Point(right-4, bottom-4)); + treasurePos = level.pointToCell(new Point(right-3, bottom-3)); + break; + case 3: + Painter.fill(level, left+2, top+3, 6, 6, Terrain.WALL ); + Painter.fill(level, left+3, top+4, 4, 4, Terrain.EMPTY_SP ); + Painter.fill(level, left+4, top+3, 2, 1, Terrain.EMPTY_SP ); + Painter.fill(level, left+7, top+5, 1, 2, Terrain.EMPTY_SP ); + ratPos = level.pointToCell(new Point(left+4, bottom-4)); + treasurePos = level.pointToCell(new Point(left+3, bottom-3)); + break; + } + + level.drop(Generator.randomWeapon(true), treasurePos).type = Heap.Type.CHEST; + + for (Door door : connected.values()) { + door.set( Door.Type.REGULAR ); + } + + VaultRat rat = new VaultRat(); + rat.pos = ratPos; + level.mobs.add(rat); + + } + + @Override + public boolean canMerge(Level l, Room other, Point p, int mergeTerrain) { + return false; + } + +}