diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java index 226036090..3ed677f12 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java @@ -366,11 +366,8 @@ public class Dungeon { Dungeon.level = level; Mob.restoreAllies( level, pos ); Actor.init(); - - Actor respawner = level.respawner(); - if (respawner != null) { - Actor.addDelayed( respawner, level.respawnTime() ); - } + + level.addRespawner(); hero.pos = pos; 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 b7b76b6d8..ca5591740 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/DeadEndLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/DeadEndLevel.java @@ -81,7 +81,7 @@ public class DeadEndLevel extends Level { protected void createMobs() { } - public Actor respawner() { + public Actor addRespawner() { return null; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastLevel.java index 98a364eef..9a0c9abac 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastLevel.java @@ -142,7 +142,7 @@ public class LastLevel extends Level { protected void createMobs() { } - public Actor respawner() { + public Actor addRespawner() { return null; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastShopLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastShopLevel.java index aaf9781d5..b26679cf4 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastShopLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/LastShopLevel.java @@ -110,7 +110,7 @@ public class LastShopLevel extends RegularLevel { protected void createMobs() { } - public Actor respawner() { + public Actor addRespawner() { return null; } 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 f5f85bc29..569438059 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java @@ -378,7 +378,11 @@ public abstract class Level implements Bundlable { if (mob != null) mobsToSpawn.add(mob); } } - + + if (bundle.contains( "respawner" )){ + respawner = (Respawner) bundle.get("respawner"); + } + buildFlagMaps(); cleanWalls(); @@ -411,6 +415,7 @@ public abstract class Level implements Bundlable { bundle.put( BLOBS, blobs.values() ); bundle.put( FEELING, feeling ); bundle.put( "mobs_to_spawn", mobsToSpawn.toArray(new Class[0])); + bundle.put( "respawner", respawner ); } public int tunnelTile() { @@ -499,43 +504,52 @@ public abstract class Level implements Bundlable { } return null; } - - public Actor respawner() { - return new Actor() { - { - actPriority = BUFF_PRIO; //as if it were a buff. - } + private Respawner respawner; - @Override - protected boolean act() { - float count = 0; - - for (Mob mob : mobs.toArray(new Mob[0])){ - if (mob.alignment == Char.Alignment.ENEMY && !mob.properties().contains(Char.Property.MINIBOSS)) { - count += mob.spawningWeight(); - } - } - - if (count < nMobs()) { - - Mob mob = createMob(); - mob.state = mob.WANDERING; - mob.pos = randomRespawnCell( mob ); - if (Dungeon.hero.isAlive() && mob.pos != -1 && distance(Dungeon.hero.pos, mob.pos) >= 4) { - GameScene.add( mob ); - if (Statistics.amuletObtained) { - mob.beckon( Dungeon.hero.pos ); - } - } - } - spend(respawnTime()); - return true; - } - }; + public Actor addRespawner() { + if (respawner == null){ + respawner = new Respawner(); + Actor.addDelayed(respawner, respawnCooldown()); + } else { + Actor.add(respawner); + } + return respawner; } - - public float respawnTime(){ + + public static class Respawner extends Actor { + { + actPriority = BUFF_PRIO; //as if it were a buff. + } + + @Override + protected boolean act() { + float count = 0; + + for (Mob mob : Dungeon.level.mobs.toArray(new Mob[0])){ + if (mob.alignment == Char.Alignment.ENEMY && !mob.properties().contains(Char.Property.MINIBOSS)) { + count += mob.spawningWeight(); + } + } + + if (count < Dungeon.level.nMobs()) { + + Mob mob = Dungeon.level.createMob(); + mob.state = mob.WANDERING; + mob.pos = Dungeon.level.randomRespawnCell( mob ); + if (Dungeon.hero.isAlive() && mob.pos != -1) { + GameScene.add( mob ); + if (Statistics.amuletObtained) { + mob.beckon( Dungeon.hero.pos ); + } + } + } + spend(Dungeon.level.respawnCooldown()); + return true; + } + } + + public float respawnCooldown(){ if (Statistics.amuletObtained){ return TIME_TO_RESPAWN/2f; } else if (Dungeon.level.feeling == Feeling.DARK){ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewCavesBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewCavesBossLevel.java index cd73cf5ca..9d35505b1 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewCavesBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewCavesBossLevel.java @@ -183,7 +183,7 @@ public class NewCavesBossLevel extends Level { } @Override - public Actor respawner() { + public Actor addRespawner() { return null; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewCityBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewCityBossLevel.java index 90d30840e..2623b03a9 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewCityBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewCityBossLevel.java @@ -226,7 +226,7 @@ public class NewCityBossLevel extends Level { protected void createMobs() { } - public Actor respawner() { + public Actor addRespawner() { return null; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewHallsBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewHallsBossLevel.java index 97dfad006..b0b22884c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewHallsBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewHallsBossLevel.java @@ -152,7 +152,7 @@ public class NewHallsBossLevel extends Level { protected void createMobs() { } - public Actor respawner() { + public Actor addRespawner() { return null; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewPrisonBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewPrisonBossLevel.java index 8be71a35a..a1be10e80 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewPrisonBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/NewPrisonBossLevel.java @@ -513,7 +513,7 @@ public class NewPrisonBossLevel extends Level { tengu = new NewTengu(); //We want to keep track of tengu independently of other mobs, he's not always in the level. } - public Actor respawner() { + public Actor addRespawner() { return null; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/OldCavesBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/OldCavesBossLevel.java index 2a96dd5da..0b1a0aff9 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/OldCavesBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/OldCavesBossLevel.java @@ -185,7 +185,7 @@ public class OldCavesBossLevel extends Level { protected void createMobs() { } - public Actor respawner() { + public Actor addRespawner() { return null; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/OldCityBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/OldCityBossLevel.java index d7a735ffb..98b95d426 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/OldCityBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/OldCityBossLevel.java @@ -154,7 +154,7 @@ public class OldCityBossLevel extends Level { protected void createMobs() { } - public Actor respawner() { + public Actor addRespawner() { return null; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/OldHallsBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/OldHallsBossLevel.java index ddd6fa749..831d68a48 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/OldHallsBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/OldHallsBossLevel.java @@ -145,7 +145,7 @@ public class OldHallsBossLevel extends Level { protected void createMobs() { } - public Actor respawner() { + public Actor addRespawner() { return null; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/OldPrisonBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/OldPrisonBossLevel.java index 0e2229d73..3d5e6a47b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/OldPrisonBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/OldPrisonBossLevel.java @@ -152,7 +152,7 @@ public class OldPrisonBossLevel extends Level { tengu = new OldTengu(); //We want to keep track of tengu independently of other mobs, he's not always in the level. } - public Actor respawner() { + public Actor addRespawner() { return null; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java index 0b63d06be..20d32f863 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java @@ -55,7 +55,9 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.traps.ExplosiveTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.FrostTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.Trap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.WornDartTrap; +import com.shatteredpixel.shatteredpixeldungeon.utils.BArray; import com.watabou.utils.Bundle; +import com.watabou.utils.PathFinder; import com.watabou.utils.Random; import java.util.ArrayList; @@ -235,7 +237,9 @@ public abstract class RegularLevel extends Level { public int randomRespawnCell( Char ch ) { int count = 0; int cell = -1; - + + PathFinder.buildDistanceMap(Dungeon.hero.pos, BArray.or(passable, avoid, null)); + while (true) { if (++count > 30) { @@ -248,12 +252,15 @@ public abstract class RegularLevel extends Level { } cell = pointToCell(room.random(1)); - if (!heroFOV[cell] - && Actor.findChar( cell ) == null + if (Actor.findChar( cell ) == null && passable[cell] && (!Char.hasProp(ch, Char.Property.LARGE) || openSpace[cell]) && room.canPlaceCharacter(cellToPoint(cell), this) && cell != exit) { + + if (heroFOV[cell] || PathFinder.distance[cell] < 12){ + continue; + } return cell; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java index e3300f160..1ad4a3676 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/SewerBossLevel.java @@ -103,7 +103,7 @@ public class SewerBossLevel extends SewerLevel { protected void createMobs() { } - public Actor respawner() { + public Actor addRespawner() { return null; }