From c097ea82265a7e7d5764cf18684a51a5b78f2b51 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Mon, 21 Mar 2022 17:01:46 -0400 Subject: [PATCH] v1.2.0: sacrificial fire now speeds up enemy spawns if none are alive --- .../actors/blobs/SacrificialFire.java | 29 ++++++++++ .../shatteredpixeldungeon/levels/Level.java | 56 +++++++++++-------- .../levels/RegularLevel.java | 4 +- 3 files changed, 65 insertions(+), 24 deletions(-) diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/blobs/SacrificialFire.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/blobs/SacrificialFire.java index 3596a5f44..0e6ea8667 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/blobs/SacrificialFire.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/blobs/SacrificialFire.java @@ -41,6 +41,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SacrificeRo import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.watabou.noosa.audio.Sample; +import com.watabou.utils.Bundle; import com.watabou.utils.PathFinder; import com.watabou.utils.Random; @@ -53,6 +54,10 @@ public class SacrificialFire extends Blob { actPriority = MOB_PRIO-1; } + //Can spawn extra mobs to make sacrificing less tedious + // The limit is to prevent farming + private int bonusSpawns = 3; + @Override protected void evolve() { int cell; @@ -70,6 +75,15 @@ public class SacrificialFire extends Blob { } Buff.prolong( ch, Marked.class, Marked.DURATION ); } + + if (off[cell] > 0 + && Dungeon.level.heroFOV[cell] + && Dungeon.level.mobCount() == 0 + && bonusSpawns > 0){ + if (Dungeon.level.spawnMob(4)) { + bonusSpawns--; + } + } } } } @@ -94,6 +108,20 @@ public class SacrificialFire extends Blob { return Messages.get(this, "desc"); } + private static final String BONUS_SPAWNS = "bonus_spawns"; + + @Override + public void storeInBundle(Bundle bundle) { + super.storeInBundle(bundle); + bundle.put(BONUS_SPAWNS, bonusSpawns); + } + + @Override + public void restoreFromBundle(Bundle bundle) { + super.restoreFromBundle(bundle); + bonusSpawns = bundle.getInt(BONUS_SPAWNS); + } + public static void sacrifice( Char ch ) { SacrificialFire fire = (SacrificialFire)Dungeon.level.blobs.get( SacrificialFire.class ); @@ -123,6 +151,7 @@ public class SacrificialFire extends Blob { if (volume > 0) { fire.cur[ch.pos] -= exp; fire.volume -= exp; + fire.bonusSpawns++; CellEmitter.get(ch.pos).burst( SacrificialParticle.FACTORY, 20 ); Sample.INSTANCE.play(Assets.Sounds.BURNING ); GLog.w( Messages.get(SacrificialFire.class, "worthy")); 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 be918ed30..b634e1421 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java @@ -521,10 +521,20 @@ public abstract class Level implements Bundlable { return visuals; } - public int nMobs() { + public int mobLimit() { return 0; } + public int mobCount(){ + int 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(); + } + } + return count; + } + public Mob findMob( int pos ){ for (Mob mob : mobs){ if (mob.pos == pos){ @@ -553,34 +563,16 @@ public abstract class Level implements Bundlable { @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 (Dungeon.level.mobCount() < Dungeon.level.mobLimit()) { - if (count < Dungeon.level.nMobs()) { - - PathFinder.buildDistanceMap(Dungeon.hero.pos, BArray.or(Dungeon.level.passable, Dungeon.level.avoid, null)); - - Mob mob = Dungeon.level.createMob(); - mob.state = mob.WANDERING; - mob.pos = Dungeon.level.randomRespawnCell( mob ); - if (Dungeon.hero.isAlive() && mob.pos != -1 && PathFinder.distance[mob.pos] >= 12) { - GameScene.add( mob ); - if (Statistics.amuletObtained) { - mob.beckon( Dungeon.hero.pos ); - } - if (!mob.buffs(ChampionEnemy.class).isEmpty()){ - GLog.w(Messages.get(ChampionEnemy.class, "warn")); - } + if (Dungeon.level.spawnMob(12)){ spend(Dungeon.level.respawnCooldown()); } else { //try again in 1 turn spend(TICK); } + } else { spend(Dungeon.level.respawnCooldown()); } @@ -598,6 +590,26 @@ public abstract class Level implements Bundlable { return TIME_TO_RESPAWN; } } + + public boolean spawnMob(int disLimit){ + PathFinder.buildDistanceMap(Dungeon.hero.pos, BArray.or(Dungeon.level.passable, Dungeon.level.avoid, null)); + + Mob mob = Dungeon.level.createMob(); + mob.state = mob.WANDERING; + mob.pos = Dungeon.level.randomRespawnCell( mob ); + if (Dungeon.hero.isAlive() && mob.pos != -1 && PathFinder.distance[mob.pos] >= disLimit) { + GameScene.add( mob ); + if (Statistics.amuletObtained) { + mob.beckon( Dungeon.hero.pos ); + } + if (!mob.buffs(ChampionEnemy.class).isEmpty()){ + GLog.w(Messages.get(ChampionEnemy.class, "warn")); + } + return true; + } else { + return false; + } + } public int randomRespawnCell( Char ch ) { int cell; 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 bac305c08..6ed69a3bf 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/RegularLevel.java @@ -178,7 +178,7 @@ public abstract class RegularLevel extends Level { } @Override - public int nMobs() { + public int mobLimit() { if (Dungeon.depth <= 1) return 0; int mobs = 3 + Dungeon.depth % 5 + Random.Int(3); @@ -191,7 +191,7 @@ public abstract class RegularLevel extends Level { @Override protected void createMobs() { //on floor 1, 8 pre-set mobs are created so the player can get level 2. - int mobsToSpawn = Dungeon.depth == 1 ? 8 : nMobs(); + int mobsToSpawn = Dungeon.depth == 1 ? 8 : mobLimit(); ArrayList stdRooms = new ArrayList<>(); for (Room room : rooms) {