v0.7.0: fixed various issues caused by assuming bombs destroy terrain

This commit is contained in:
Evan Debenham
2018-10-01 03:14:36 -04:00
parent 0f4dadc229
commit 2b90528004
12 changed files with 90 additions and 113 deletions
@@ -247,9 +247,10 @@ public class Heap implements Bundlable {
} else if (item instanceof Bomb) { } else if (item instanceof Bomb) {
items.remove( item ); items.remove( item );
((Bomb) item).explode( pos ); ((Bomb) item).explode( pos );
burnt = true; if (((Bomb) item).explodesDestructively()) {
//stop processing the burning, it will be replaced by the explosion. //stop processing the burning, it will be replaced by the explosion.
break; return;
}
} }
} }
@@ -298,8 +299,10 @@ public class Heap implements Bundlable {
} else if (item instanceof Bomb) { } else if (item instanceof Bomb) {
items.remove( item ); items.remove( item );
((Bomb) item).explode(pos); ((Bomb) item).explode(pos);
//stop processing current explosion, it will be replaced by the new one. if (((Bomb) item).explodesDestructively()) {
return; //stop processing current explosion, it will be replaced by the new one.
return;
}
//unique and upgraded items can endure the blast //unique and upgraded items can endure the blast
} else if (!(item.level() > 0 || item.unique)) } else if (!(item.level() > 0 || item.unique))
@@ -21,7 +21,6 @@
package com.shatteredpixel.shatteredpixeldungeon.items.bombs; package com.shatteredpixel.shatteredpixeldungeon.items.bombs;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
@@ -32,14 +31,12 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray; import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.PathFinder; import com.watabou.utils.PathFinder;
import com.watabou.utils.Random; import com.watabou.utils.Random;
public class ArcaneBomb extends Bomb { public class ArcaneBomb extends Bomb {
{ {
//TODO visuals
image = ItemSpriteSheet.ARCANE_BOMB; image = ItemSpriteSheet.ARCANE_BOMB;
} }
@@ -55,14 +52,14 @@ public class ArcaneBomb extends Bomb {
} }
} }
@Override
public boolean explodesDestructively() {
return false;
}
@Override @Override
public void explode(int cell) { public void explode(int cell) {
//We're blowing up, so no need for a fuse anymore. super.explode(cell);
this.fuse = null;
Sample.INSTANCE.play( Assets.SND_BURNING );
//no regular explosion damage
PathFinder.buildDistanceMap( cell, BArray.not( Dungeon.level.solid, null ), 2 ); PathFinder.buildDistanceMap( cell, BArray.not( Dungeon.level.solid, null ), 2 );
for (int i = 0; i < PathFinder.distance.length; i++) { for (int i = 0; i < PathFinder.distance.length; i++) {
@@ -81,6 +81,10 @@ public class Bomb extends Item {
public boolean isSimilar(Item item) { public boolean isSimilar(Item item) {
return super.isSimilar(item) && this.fuse == ((Bomb) item).fuse; return super.isSimilar(item) && this.fuse == ((Bomb) item).fuse;
} }
public boolean explodesDestructively(){
return true;
}
@Override @Override
public ArrayList<String> actions(Hero hero) { public ArrayList<String> actions(Hero hero) {
@@ -132,48 +136,50 @@ public class Bomb extends Item {
Sample.INSTANCE.play( Assets.SND_BLAST ); Sample.INSTANCE.play( Assets.SND_BLAST );
if (Dungeon.level.heroFOV[cell]) { if (explodesDestructively()) {
CellEmitter.center( cell ).burst( BlastParticle.FACTORY, 30 ); if (Dungeon.level.heroFOV[cell]) {
} CellEmitter.center(cell).burst(BlastParticle.FACTORY, 30);
}
boolean terrainAffected = false;
for (int n : PathFinder.NEIGHBOURS9) { boolean terrainAffected = false;
int c = cell + n; for (int n : PathFinder.NEIGHBOURS9) {
if (c >= 0 && c < Dungeon.level.length()) { int c = cell + n;
if (Dungeon.level.heroFOV[c]) { if (c >= 0 && c < Dungeon.level.length()) {
CellEmitter.get( c ).burst( SmokeParticle.FACTORY, 4 ); if (Dungeon.level.heroFOV[c]) {
} CellEmitter.get(c).burst(SmokeParticle.FACTORY, 4);
}
if (Dungeon.level.flamable[c]) {
Dungeon.level.destroy( c ); if (Dungeon.level.flamable[c]) {
GameScene.updateMap( c ); Dungeon.level.destroy(c);
terrainAffected = true; GameScene.updateMap(c);
} terrainAffected = true;
}
//destroys items / triggers bombs caught in the blast.
Heap heap = Dungeon.level.heaps.get( c ); //destroys items / triggers bombs caught in the blast.
if(heap != null) Heap heap = Dungeon.level.heaps.get(c);
heap.explode(); if (heap != null)
heap.explode();
Char ch = Actor.findChar( c );
if (ch != null) { Char ch = Actor.findChar(c);
//those not at the center of the blast take damage less consistently. if (ch != null) {
int minDamage = c == cell ? Dungeon.depth+5 : 1; //those not at the center of the blast take damage less consistently.
int maxDamage = 10 + Dungeon.depth * 2; int minDamage = c == cell ? Dungeon.depth + 5 : 1;
int maxDamage = 10 + Dungeon.depth * 2;
int dmg = Random.NormalIntRange( minDamage, maxDamage ) - ch.drRoll();
if (dmg > 0) { int dmg = Random.NormalIntRange(minDamage, maxDamage) - ch.drRoll();
ch.damage( dmg, this ); if (dmg > 0) {
ch.damage(dmg, this);
}
if (ch == Dungeon.hero && !ch.isAlive())
Dungeon.fail(Bomb.class);
} }
if (ch == Dungeon.hero && !ch.isAlive())
Dungeon.fail( Bomb.class );
} }
} }
}
if (terrainAffected) {
if (terrainAffected) { Dungeon.observe();
Dungeon.observe(); }
} }
} }
@@ -36,7 +36,6 @@ import com.watabou.utils.PathFinder;
public class Firebomb extends Bomb { public class Firebomb extends Bomb {
{ {
//TODO visuals
image = ItemSpriteSheet.FIRE_BOMB; image = ItemSpriteSheet.FIRE_BOMB;
} }
@@ -21,39 +21,30 @@
package com.shatteredpixel.shatteredpixeldungeon.items.bombs; package com.shatteredpixel.shatteredpixeldungeon.items.bombs;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Blindness; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Blindness;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Cripple; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Cripple;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.BlastParticle;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.noosa.audio.Sample;
public class Flashbang extends Bomb { public class Flashbang extends Bomb {
{ {
//TODO visuals
image = ItemSpriteSheet.FLASHBANG; image = ItemSpriteSheet.FLASHBANG;
} }
@Override
public boolean explodesDestructively() {
return false;
}
@Override @Override
public void explode(int cell) { public void explode(int cell) {
//We're blowing up, so no need for a fuse anymore. super.explode(cell);
this.fuse = null;
Sample.INSTANCE.play( Assets.SND_BLAST );
if (Dungeon.level.heroFOV[cell]) {
CellEmitter.center( cell ).burst( BlastParticle.FACTORY, 30 );
}
//no regular explosion damage
//FIXME currently has somewhat odd behaviour, as FOV is updated at the start of a turn. //FIXME currently has somewhat odd behaviour, as FOV is updated at the start of a turn.
Level l = Dungeon.level; Level l = Dungeon.level;
@@ -32,7 +32,6 @@ import com.watabou.utils.PathFinder;
public class FrostBomb extends Bomb { public class FrostBomb extends Bomb {
{ {
//TODO visuals
image = ItemSpriteSheet.FROST_BOMB; image = ItemSpriteSheet.FROST_BOMB;
} }
@@ -39,7 +39,6 @@ import com.watabou.utils.Random;
public class HolyBomb extends Bomb { public class HolyBomb extends Bomb {
{ {
//TODO visuals
image = ItemSpriteSheet.HOLY_BOMB; image = ItemSpriteSheet.HOLY_BOMB;
} }
@@ -27,7 +27,6 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.BlastParticle;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.noosa.audio.Sample; import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Bundle; import com.watabou.utils.Bundle;
@@ -35,22 +34,18 @@ import com.watabou.utils.Bundle;
public class Noisemaker extends Bomb { public class Noisemaker extends Bomb {
{ {
//TODO visuals
image = ItemSpriteSheet.NOISEMAKER; image = ItemSpriteSheet.NOISEMAKER;
} }
@Override
public boolean explodesDestructively() {
return false;
}
@Override @Override
public void explode(int cell) { public void explode(int cell) {
//We're blowing up, so no need for a fuse anymore. super.explode(cell);
this.fuse = null;
Sample.INSTANCE.play( Assets.SND_BLAST );
if (Dungeon.level.heroFOV[cell]) {
CellEmitter.center( cell ).burst( BlastParticle.FACTORY, 30 );
}
//no regular explosion damage
Buff.affect(Dungeon.hero, Noise.class).set(cell); Buff.affect(Dungeon.hero, Noise.class).set(cell);
} }
@@ -21,7 +21,6 @@
package com.shatteredpixel.shatteredpixeldungeon.items.bombs; package com.shatteredpixel.shatteredpixeldungeon.items.bombs;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
@@ -38,7 +37,6 @@ import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray; import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.PathFinder; import com.watabou.utils.PathFinder;
import com.watabou.utils.Random; import com.watabou.utils.Random;
@@ -51,19 +49,19 @@ public class RegrowthBomb extends Bomb {
image = ItemSpriteSheet.REGROWTH_BOMB; image = ItemSpriteSheet.REGROWTH_BOMB;
} }
@Override
public boolean explodesDestructively() {
return false;
}
@Override @Override
public void explode(int cell) { public void explode(int cell) {
//We're blowing up, so no need for a fuse anymore. super.explode(cell);
this.fuse = null;
Sample.INSTANCE.play( Assets.SND_BLAST );
if (Dungeon.level.heroFOV[cell]) { if (Dungeon.level.heroFOV[cell]) {
Splash.at(cell, 0x00FF00, 30); Splash.at(cell, 0x00FF00, 30);
} }
//no regular explosion damage
ArrayList<Integer> plantCandidates = new ArrayList<>(); ArrayList<Integer> plantCandidates = new ArrayList<>();
PathFinder.buildDistanceMap( cell, BArray.not( Dungeon.level.solid, null ), 2 ); PathFinder.buildDistanceMap( cell, BArray.not( Dungeon.level.solid, null ), 2 );
@@ -34,7 +34,6 @@ import com.watabou.utils.PathFinder;
public class ShockBomb extends Bomb { public class ShockBomb extends Bomb {
{ {
//TODO visuals
image = ItemSpriteSheet.SHOCK_BOMB; image = ItemSpriteSheet.SHOCK_BOMB;
} }
@@ -21,7 +21,6 @@
package com.shatteredpixel.shatteredpixeldungeon.items.bombs; package com.shatteredpixel.shatteredpixeldungeon.items.bombs;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
@@ -29,25 +28,23 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.BlastParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.BlastParticle;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.ShadowCaster; import com.shatteredpixel.shatteredpixeldungeon.mechanics.ShadowCaster;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Point; import com.watabou.utils.Point;
import com.watabou.utils.Random; import com.watabou.utils.Random;
public class ShrapnelBomb extends Bomb { public class ShrapnelBomb extends Bomb {
{ {
//TODO visuals
image = ItemSpriteSheet.SHRAPNEL_BOMB; image = ItemSpriteSheet.SHRAPNEL_BOMB;
} }
@Override
public boolean explodesDestructively() {
return false;
}
@Override @Override
public void explode(int cell) { public void explode(int cell) {
//We're blowing up, so no need for a fuse anymore. super.explode(cell);
this.fuse = null;
Sample.INSTANCE.play( Assets.SND_BURNING );
//no regular explosion damage
boolean[] FOV = new boolean[Dungeon.level.length()]; boolean[] FOV = new boolean[Dungeon.level.length()];
Point c = Dungeon.level.cellToPoint(cell); Point c = Dungeon.level.cellToPoint(cell);
@@ -27,7 +27,6 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Sheep; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Sheep;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.BlastParticle;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray; import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
@@ -38,22 +37,17 @@ import com.watabou.utils.Random;
public class WoollyBomb extends Bomb { public class WoollyBomb extends Bomb {
{ {
//TODO visuals
image = ItemSpriteSheet.WOOLY_BOMB; image = ItemSpriteSheet.WOOLY_BOMB;
} }
@Override
public boolean explodesDestructively() {
return false;
}
@Override @Override
public void explode(int cell) { public void explode(int cell) {
//We're blowing up, so no need for a fuse anymore. super.explode(cell);
this.fuse = null;
Sample.INSTANCE.play( Assets.SND_BLAST );
if (Dungeon.level.heroFOV[cell]) {
CellEmitter.center( cell ).burst( BlastParticle.FACTORY, 30 );
}
//no regular explosion damage
PathFinder.buildDistanceMap( cell, BArray.not( Dungeon.level.solid, null ), 2 ); PathFinder.buildDistanceMap( cell, BArray.not( Dungeon.level.solid, null ), 2 );
for (int i = 0; i < PathFinder.distance.length; i++) { for (int i = 0; i < PathFinder.distance.length; i++) {