diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/NewDM300.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/NewDM300.java index 205f2882d..da7b6f75a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/NewDM300.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/NewDM300.java @@ -33,6 +33,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Charm; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Chill; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Cripple; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FlavourBuff; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Frost; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LockedFloor; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis; @@ -41,7 +42,6 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Sleep; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Slow; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo; -import com.shatteredpixel.shatteredpixeldungeon.effects.BlobEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.EarthParticle; @@ -58,16 +58,20 @@ import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.DM300Sprite; +import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap; import com.shatteredpixel.shatteredpixeldungeon.ui.BossHealthBar; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.watabou.noosa.Camera; import com.watabou.noosa.audio.Sample; +import com.watabou.noosa.particles.Emitter; import com.watabou.utils.Bundle; import com.watabou.utils.PathFinder; import com.watabou.utils.Point; import com.watabou.utils.Random; import com.watabou.utils.Rect; -import com.watabou.utils.RectF; + +import java.util.ArrayList; +import java.util.List; public class NewDM300 extends Mob { @@ -152,7 +156,6 @@ public class NewDM300 extends Mob { @Override protected boolean act() { - GameScene.add(Blob.seed(pos, 0, FallingRocks.class)); //ability logic only triggers if DM is not supercharged if (!supercharged){ @@ -378,47 +381,33 @@ public class NewDM300 extends Mob { rockCenter = target.pos; } - //we handle this through an actor as it gives us fine-grainted control over when the blog acts vs. when the hero acts - //FIXME this is really messy to just get some fine-grained control. would be nice to build this into blob functionality, or just not use blobs for this at all - Actor a = new Actor() { + int safeCell; + do { + safeCell = rockCenter + PathFinder.NEIGHBOURS8[Random.Int(8)]; + } while (safeCell == pos + || (Dungeon.level.solid[safeCell] && Random.Int(2) == 0) + || (Blob.volumeAt(safeCell, NewCavesBossLevel.PylonEnergy.class) > 0 && Random.Int(2) == 0)); - { - actPriority = HERO_PRIO+1; - } + ArrayList rockCells = new ArrayList<>(); - @Override - protected boolean act() { - - //pick an adjacent cell to the hero as a safe cell. This cell is less likely to be in a wall or containing hazards - int safeCell; - do { - safeCell = rockCenter + PathFinder.NEIGHBOURS8[Random.Int(8)]; - } while (safeCell == pos - || (Dungeon.level.solid[safeCell] && Random.Int(2) == 0) - || (Blob.volumeAt(safeCell, NewCavesBossLevel.PylonEnergy.class) > 0 && Random.Int(2) == 0)); - - int start = rockCenter - Dungeon.level.width() * 3 - 3; - int pos; - for (int y = 0; y < 7; y++) { - pos = start + Dungeon.level.width() * y; - for (int x = 0; x < 7; x++) { - if (!Dungeon.level.insideMap(pos)) { - pos++; - continue; - } - //add rock cell to pos, if it is not solid, and isn't the safecell - if (!Dungeon.level.solid[pos] && pos != safeCell && Random.Int(Dungeon.level.distance(rockCenter, pos)) == 0) { - //don't want to overly punish players with slow move or attack speed - GameScene.add(Blob.seed(pos, 1, FallingRocks.class)); - } - pos++; - } + int start = rockCenter - Dungeon.level.width() * 3 - 3; + int pos; + for (int y = 0; y < 7; y++) { + pos = start + Dungeon.level.width() * y; + for (int x = 0; x < 7; x++) { + if (!Dungeon.level.insideMap(pos)) { + pos++; + continue; } - Actor.remove(this); - return true; + //add rock cell to pos, if it is not solid, and isn't the safecell + if (!Dungeon.level.solid[pos] && pos != safeCell && Random.Int(Dungeon.level.distance(rockCenter, pos)) == 0) { + //don't want to overly punish players with slow move or attack speed + rockCells.add(pos); + } + pos++; } - }; - Actor.addDelayed(a, Math.min(target.cooldown(), 3*TICK)); + } + Buff.append(this, FallingRocks.class, Math.min(target.cooldown(), 3*TICK)).setRockPositions(rockCells); } @@ -611,59 +600,67 @@ public class NewDM300 extends Mob { resistances.add(Slow.class); } - public static class FallingRocks extends Blob { + public static class FallingRocks extends FlavourBuff { - { - alwaysVisible = true; + private int[] rockPositions; + private ArrayList rockEmitters = new ArrayList<>(); + + public void setRockPositions( List rockPositions ) { + this.rockPositions = new int[rockPositions.size()]; + for (int i = 0; i < rockPositions.size(); i++){ + this.rockPositions[i] = rockPositions.get(i); + } + + fx(true); } @Override - protected void evolve() { + public boolean act() { + for (int i : rockPositions){ + CellEmitter.get( i ).start( Speck.factory( Speck.ROCK ), 0.07f, 10 ); - boolean rocksFell = false; - - int cell; - for (int i = area.left; i < area.right; i++){ - for (int j = area.top; j < area.bottom; j++){ - cell = i + j* Dungeon.level.width(); - off[cell] = cur[cell] > 0 ? cur[cell] - 1 : 0; - - if (off[cell] > 0) { - volume += off[cell]; - } - - if (cur[cell] > 0 && off[cell] == 0){ - - CellEmitter.get( cell ).start( Speck.factory( Speck.ROCK ), 0.07f, 10 ); - - Char ch = Actor.findChar(cell); - if (ch != null && !(ch instanceof NewDM300)){ - Buff.prolong( ch, Paralysis.class, 3 ); - } - - rocksFell = true; - } + Char ch = Actor.findChar(i); + if (ch != null && !(ch instanceof NewDM300)){ + Buff.prolong( ch, Paralysis.class, 3 ); } } - if (rocksFell){ - Camera.main.shake( 3, 0.7f ); - Sample.INSTANCE.play(Assets.Sounds.ROCKS); + Camera.main.shake( 3, 0.7f ); + Sample.INSTANCE.play(Assets.Sounds.ROCKS); + + detach(); + return super.act(); + } + + @Override + public void fx(boolean on) { + if (on && rockPositions != null){ + for (int i : this.rockPositions){ + Emitter e = CellEmitter.get(i); + e.y -= DungeonTilemap.SIZE*0.2f; + e.height *= 0.4f; + e.pour(EarthParticle.FALLING, 0.1f); + rockEmitters.add(e); + } + } else { + for (Emitter e : rockEmitters){ + e.on = false; + } } + } + private static final String POSITIONS = "positions"; + + @Override + public void storeInBundle(Bundle bundle) { + super.storeInBundle(bundle); + bundle.put(POSITIONS, rockPositions); } @Override - public void use(BlobEmitter emitter) { - super.use(emitter); - - emitter.bound = new RectF(0, -0.2f, 1, 0.4f); - emitter.pour(EarthParticle.FALLING, 0.1f); - } - - @Override - public String tileDesc() { - return Messages.get(this, "desc"); + public void restoreFromBundle(Bundle bundle) { + super.restoreFromBundle(bundle); + rockPositions = bundle.getIntArray(POSITIONS); } } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/NewTengu.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/NewTengu.java index 9ddc00bd5..cf4a8f83c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/NewTengu.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/NewTengu.java @@ -576,14 +576,7 @@ public class NewTengu extends Mob { public boolean act() { if (smokeEmitters.isEmpty()){ - PathFinder.buildDistanceMap( bombPos, BArray.not( Dungeon.level.solid, null ), 2 ); - for (int i = 0; i < PathFinder.distance.length; i++) { - if (PathFinder.distance[i] < Integer.MAX_VALUE) { - Emitter e = CellEmitter.get(i); - e.pour( SmokeParticle.FACTORY, 0.25f ); - smokeEmitters.add(e); - } - } + fx(true); } PointF p = DungeonTilemap.raisedTileCenterToWorld(bombPos);