v1.2.0: sacrificial fire now speeds up enemy spawns if none are alive

This commit is contained in:
Evan Debenham 2022-03-21 17:01:46 -04:00
parent f9bd72cd5e
commit c097ea8226
3 changed files with 65 additions and 24 deletions

View File

@ -41,6 +41,7 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SacrificeRo
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.audio.Sample; import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Bundle;
import com.watabou.utils.PathFinder; import com.watabou.utils.PathFinder;
import com.watabou.utils.Random; import com.watabou.utils.Random;
@ -53,6 +54,10 @@ public class SacrificialFire extends Blob {
actPriority = MOB_PRIO-1; actPriority = MOB_PRIO-1;
} }
//Can spawn extra mobs to make sacrificing less tedious
// The limit is to prevent farming
private int bonusSpawns = 3;
@Override @Override
protected void evolve() { protected void evolve() {
int cell; int cell;
@ -70,6 +75,15 @@ public class SacrificialFire extends Blob {
} }
Buff.prolong( ch, Marked.class, Marked.DURATION ); 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"); 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 ) { public static void sacrifice( Char ch ) {
SacrificialFire fire = (SacrificialFire)Dungeon.level.blobs.get( SacrificialFire.class ); SacrificialFire fire = (SacrificialFire)Dungeon.level.blobs.get( SacrificialFire.class );
@ -123,6 +151,7 @@ public class SacrificialFire extends Blob {
if (volume > 0) { if (volume > 0) {
fire.cur[ch.pos] -= exp; fire.cur[ch.pos] -= exp;
fire.volume -= exp; fire.volume -= exp;
fire.bonusSpawns++;
CellEmitter.get(ch.pos).burst( SacrificialParticle.FACTORY, 20 ); CellEmitter.get(ch.pos).burst( SacrificialParticle.FACTORY, 20 );
Sample.INSTANCE.play(Assets.Sounds.BURNING ); Sample.INSTANCE.play(Assets.Sounds.BURNING );
GLog.w( Messages.get(SacrificialFire.class, "worthy")); GLog.w( Messages.get(SacrificialFire.class, "worthy"));

View File

@ -521,10 +521,20 @@ public abstract class Level implements Bundlable {
return visuals; return visuals;
} }
public int nMobs() { public int mobLimit() {
return 0; 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 ){ public Mob findMob( int pos ){
for (Mob mob : mobs){ for (Mob mob : mobs){
if (mob.pos == pos){ if (mob.pos == pos){
@ -553,34 +563,16 @@ public abstract class Level implements Bundlable {
@Override @Override
protected boolean act() { protected boolean act() {
float count = 0;
for (Mob mob : Dungeon.level.mobs.toArray(new Mob[0])){ if (Dungeon.level.mobCount() < Dungeon.level.mobLimit()) {
if (mob.alignment == Char.Alignment.ENEMY && !mob.properties().contains(Char.Property.MINIBOSS)) {
count += mob.spawningWeight();
}
}
if (count < Dungeon.level.nMobs()) { if (Dungeon.level.spawnMob(12)){
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"));
}
spend(Dungeon.level.respawnCooldown()); spend(Dungeon.level.respawnCooldown());
} else { } else {
//try again in 1 turn //try again in 1 turn
spend(TICK); spend(TICK);
} }
} else { } else {
spend(Dungeon.level.respawnCooldown()); spend(Dungeon.level.respawnCooldown());
} }
@ -599,6 +591,26 @@ public abstract class Level implements Bundlable {
} }
} }
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 ) { public int randomRespawnCell( Char ch ) {
int cell; int cell;
do { do {

View File

@ -178,7 +178,7 @@ public abstract class RegularLevel extends Level {
} }
@Override @Override
public int nMobs() { public int mobLimit() {
if (Dungeon.depth <= 1) return 0; if (Dungeon.depth <= 1) return 0;
int mobs = 3 + Dungeon.depth % 5 + Random.Int(3); int mobs = 3 + Dungeon.depth % 5 + Random.Int(3);
@ -191,7 +191,7 @@ public abstract class RegularLevel extends Level {
@Override @Override
protected void createMobs() { protected void createMobs() {
//on floor 1, 8 pre-set mobs are created so the player can get level 2. //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<Room> stdRooms = new ArrayList<>(); ArrayList<Room> stdRooms = new ArrayList<>();
for (Room room : rooms) { for (Room room : rooms) {