diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/CorpseDust.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/CorpseDust.java index 56d434f5d..f1b658ce1 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/CorpseDust.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/CorpseDust.java @@ -107,20 +107,26 @@ public class CorpseDust extends Item { } } - int powerNeeded = Math.min(25, wraiths*wraiths); - + //summoning a new wraith requires 1/4/9/16/25/36/49/49/... turns of energy + //note that logic for summoning wraiths kind of has an odd, undocumented balance history: + //v0.3.1-v0.6.5: wraith every 1/4/9/16/25/25... turns, basically guaranteed + //v0.7.0-v2.1.4: bugged, same rate as above but high (often >50%) chance that spawning fails. failed spawning resets delay! + //v2.2.0+: fixed bug, increased summon delay cap to counteract a bit, wraiths also now have to spawn at a slight distance + int powerNeeded = Math.min(49, wraiths*wraiths); if (powerNeeded <= spawnPower){ - spawnPower -= powerNeeded; - int pos = 0; - //FIXME this seems like old bad code (why not more checks at least?) but corpse dust may be balanced around it - int tries = 20; - do{ - pos = Random.Int(Dungeon.level.length()); - tries --; - } while (tries > 0 && (!Dungeon.level.heroFOV[pos] || Dungeon.level.solid[pos] || Actor.findChar( pos ) != null)); - if (tries > 0) { - Wraith.spawnAt(pos, false); + ArrayList candidates = new ArrayList<>(); + for (int i = 0; i < Dungeon.level.length(); i++){ + if (Dungeon.level.heroFOV[i] + && !Dungeon.level.solid[i] + && Actor.findChar( i ) == null + && Dungeon.level.distance(i, Dungeon.hero.pos) > 3){ + candidates.add(i); + } + } + if (!candidates.isEmpty()){ + Wraith.spawnAt(Random.element(candidates), false); Sample.INSTANCE.play(Assets.Sounds.CURSED); + spawnPower -= powerNeeded; } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MassGraveRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MassGraveRoom.java index cd107c07a..a13b22dde 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MassGraveRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/MassGraveRoom.java @@ -32,6 +32,8 @@ import com.shatteredpixel.shatteredpixeldungeon.items.quest.CorpseDust; 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.EntranceRoom; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.tiles.CustomTilemap; import com.watabou.noosa.Image; @@ -95,6 +97,32 @@ public class MassGraveRoom extends SpecialRoom { } } + @Override + public boolean canConnect(Room r) { + if (r instanceof EntranceRoom){ + return false; + } + + //must have at least 3 rooms between it and the entrance room + for (Room r1 : r.connected.keySet()) { + if (r1 instanceof EntranceRoom){ + return false; + } + for (Room r2 : r1.connected.keySet()) { + if (r2 instanceof EntranceRoom){ + return false; + } + for (Room r3 : r2.connected.keySet()) { + if (r3 instanceof EntranceRoom){ + return false; + } + } + } + } + + return super.canConnect(r); + } + public static class Bones extends CustomTilemap { private static final int WALL_OVERLAP = 3;