v0.8.2a: adjusted level spawner mechanics:

- current spawn cooldown is now properly stored/loaded
- enemies now much spawn at least 12 tiles away from the hero
This commit is contained in:
Evan Debenham 2020-08-14 22:41:17 -04:00
parent b8178b15b7
commit 789314e5c7
15 changed files with 73 additions and 55 deletions

View File

@ -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;

View File

@ -81,7 +81,7 @@ public class DeadEndLevel extends Level {
protected void createMobs() {
}
public Actor respawner() {
public Actor addRespawner() {
return null;
}

View File

@ -142,7 +142,7 @@ public class LastLevel extends Level {
protected void createMobs() {
}
public Actor respawner() {
public Actor addRespawner() {
return null;
}

View File

@ -110,7 +110,7 @@ public class LastShopLevel extends RegularLevel {
protected void createMobs() {
}
public Actor respawner() {
public Actor addRespawner() {
return null;
}

View File

@ -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){

View File

@ -183,7 +183,7 @@ public class NewCavesBossLevel extends Level {
}
@Override
public Actor respawner() {
public Actor addRespawner() {
return null;
}

View File

@ -226,7 +226,7 @@ public class NewCityBossLevel extends Level {
protected void createMobs() {
}
public Actor respawner() {
public Actor addRespawner() {
return null;
}

View File

@ -152,7 +152,7 @@ public class NewHallsBossLevel extends Level {
protected void createMobs() {
}
public Actor respawner() {
public Actor addRespawner() {
return null;
}

View File

@ -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;
}

View File

@ -185,7 +185,7 @@ public class OldCavesBossLevel extends Level {
protected void createMobs() {
}
public Actor respawner() {
public Actor addRespawner() {
return null;
}

View File

@ -154,7 +154,7 @@ public class OldCityBossLevel extends Level {
protected void createMobs() {
}
public Actor respawner() {
public Actor addRespawner() {
return null;
}

View File

@ -145,7 +145,7 @@ public class OldHallsBossLevel extends Level {
protected void createMobs() {
}
public Actor respawner() {
public Actor addRespawner() {
return null;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -103,7 +103,7 @@ public class SewerBossLevel extends SewerLevel {
protected void createMobs() {
}
public Actor respawner() {
public Actor addRespawner() {
return null;
}