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

View File

@ -247,9 +247,10 @@ public class Heap implements Bundlable {
} else if (item instanceof Bomb) {
items.remove( item );
((Bomb) item).explode( pos );
burnt = true;
//stop processing the burning, it will be replaced by the explosion.
break;
if (((Bomb) item).explodesDestructively()) {
//stop processing the burning, it will be replaced by the explosion.
return;
}
}
}
@ -298,8 +299,10 @@ public class Heap implements Bundlable {
} else if (item instanceof Bomb) {
items.remove( item );
((Bomb) item).explode(pos);
//stop processing current explosion, it will be replaced by the new one.
return;
if (((Bomb) item).explodesDestructively()) {
//stop processing current explosion, it will be replaced by the new one.
return;
}
//unique and upgraded items can endure the blast
} else if (!(item.level() > 0 || item.unique))

View File

@ -21,7 +21,6 @@
package com.shatteredpixel.shatteredpixeldungeon.items.bombs;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
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.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Random;
public class ArcaneBomb extends Bomb {
{
//TODO visuals
image = ItemSpriteSheet.ARCANE_BOMB;
}
@ -55,14 +52,14 @@ public class ArcaneBomb extends Bomb {
}
}
@Override
public boolean explodesDestructively() {
return false;
}
@Override
public void explode(int cell) {
//We're blowing up, so no need for a fuse anymore.
this.fuse = null;
Sample.INSTANCE.play( Assets.SND_BURNING );
//no regular explosion damage
super.explode(cell);
PathFinder.buildDistanceMap( cell, BArray.not( Dungeon.level.solid, null ), 2 );
for (int i = 0; i < PathFinder.distance.length; i++) {

View File

@ -81,6 +81,10 @@ public class Bomb extends Item {
public boolean isSimilar(Item item) {
return super.isSimilar(item) && this.fuse == ((Bomb) item).fuse;
}
public boolean explodesDestructively(){
return true;
}
@Override
public ArrayList<String> actions(Hero hero) {
@ -132,48 +136,50 @@ public class Bomb extends Item {
Sample.INSTANCE.play( Assets.SND_BLAST );
if (Dungeon.level.heroFOV[cell]) {
CellEmitter.center( cell ).burst( BlastParticle.FACTORY, 30 );
}
boolean terrainAffected = false;
for (int n : PathFinder.NEIGHBOURS9) {
int c = cell + n;
if (c >= 0 && c < Dungeon.level.length()) {
if (Dungeon.level.heroFOV[c]) {
CellEmitter.get( c ).burst( SmokeParticle.FACTORY, 4 );
}
if (Dungeon.level.flamable[c]) {
Dungeon.level.destroy( c );
GameScene.updateMap( c );
terrainAffected = true;
}
//destroys items / triggers bombs caught in the blast.
Heap heap = Dungeon.level.heaps.get( c );
if(heap != null)
heap.explode();
Char ch = Actor.findChar( c );
if (ch != null) {
//those not at the center of the blast take damage less consistently.
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) {
ch.damage( dmg, this );
if (explodesDestructively()) {
if (Dungeon.level.heroFOV[cell]) {
CellEmitter.center(cell).burst(BlastParticle.FACTORY, 30);
}
boolean terrainAffected = false;
for (int n : PathFinder.NEIGHBOURS9) {
int c = cell + n;
if (c >= 0 && c < Dungeon.level.length()) {
if (Dungeon.level.heroFOV[c]) {
CellEmitter.get(c).burst(SmokeParticle.FACTORY, 4);
}
if (Dungeon.level.flamable[c]) {
Dungeon.level.destroy(c);
GameScene.updateMap(c);
terrainAffected = true;
}
//destroys items / triggers bombs caught in the blast.
Heap heap = Dungeon.level.heaps.get(c);
if (heap != null)
heap.explode();
Char ch = Actor.findChar(c);
if (ch != null) {
//those not at the center of the blast take damage less consistently.
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) {
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) {
Dungeon.observe();
if (terrainAffected) {
Dungeon.observe();
}
}
}

View File

@ -36,7 +36,6 @@ import com.watabou.utils.PathFinder;
public class Firebomb extends Bomb {
{
//TODO visuals
image = ItemSpriteSheet.FIRE_BOMB;
}

View File

@ -21,39 +21,30 @@
package com.shatteredpixel.shatteredpixeldungeon.items.bombs;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Blindness;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
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.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.noosa.audio.Sample;
public class Flashbang extends Bomb {
{
//TODO visuals
image = ItemSpriteSheet.FLASHBANG;
}
@Override
public boolean explodesDestructively() {
return false;
}
@Override
public void explode(int cell) {
//We're blowing up, so no need for a fuse anymore.
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
super.explode(cell);
//FIXME currently has somewhat odd behaviour, as FOV is updated at the start of a turn.
Level l = Dungeon.level;

View File

@ -32,7 +32,6 @@ import com.watabou.utils.PathFinder;
public class FrostBomb extends Bomb {
{
//TODO visuals
image = ItemSpriteSheet.FROST_BOMB;
}

View File

@ -39,7 +39,6 @@ import com.watabou.utils.Random;
public class HolyBomb extends Bomb {
{
//TODO visuals
image = ItemSpriteSheet.HOLY_BOMB;
}

View File

@ -27,7 +27,6 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.BlastParticle;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Bundle;
@ -35,22 +34,18 @@ import com.watabou.utils.Bundle;
public class Noisemaker extends Bomb {
{
//TODO visuals
image = ItemSpriteSheet.NOISEMAKER;
}
@Override
public boolean explodesDestructively() {
return false;
}
@Override
public void explode(int cell) {
//We're blowing up, so no need for a fuse anymore.
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
super.explode(cell);
Buff.affect(Dungeon.hero, Noise.class).set(cell);
}

View File

@ -21,7 +21,6 @@
package com.shatteredpixel.shatteredpixeldungeon.items.bombs;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
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.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Random;
@ -51,19 +49,19 @@ public class RegrowthBomb extends Bomb {
image = ItemSpriteSheet.REGROWTH_BOMB;
}
@Override
public boolean explodesDestructively() {
return false;
}
@Override
public void explode(int cell) {
//We're blowing up, so no need for a fuse anymore.
this.fuse = null;
Sample.INSTANCE.play( Assets.SND_BLAST );
super.explode(cell);
if (Dungeon.level.heroFOV[cell]) {
Splash.at(cell, 0x00FF00, 30);
}
//no regular explosion damage
ArrayList<Integer> plantCandidates = new ArrayList<>();
PathFinder.buildDistanceMap( cell, BArray.not( Dungeon.level.solid, null ), 2 );

View File

@ -34,7 +34,6 @@ import com.watabou.utils.PathFinder;
public class ShockBomb extends Bomb {
{
//TODO visuals
image = ItemSpriteSheet.SHOCK_BOMB;
}

View File

@ -21,7 +21,6 @@
package com.shatteredpixel.shatteredpixeldungeon.items.bombs;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
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.mechanics.ShadowCaster;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Point;
import com.watabou.utils.Random;
public class ShrapnelBomb extends Bomb {
{
//TODO visuals
image = ItemSpriteSheet.SHRAPNEL_BOMB;
}
@Override
public boolean explodesDestructively() {
return false;
}
@Override
public void explode(int cell) {
//We're blowing up, so no need for a fuse anymore.
this.fuse = null;
Sample.INSTANCE.play( Assets.SND_BURNING );
//no regular explosion damage
super.explode(cell);
boolean[] FOV = new boolean[Dungeon.level.length()];
Point c = Dungeon.level.cellToPoint(cell);

View File

@ -27,7 +27,6 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Sheep;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.BlastParticle;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
@ -38,22 +37,17 @@ import com.watabou.utils.Random;
public class WoollyBomb extends Bomb {
{
//TODO visuals
image = ItemSpriteSheet.WOOLY_BOMB;
}
@Override
public boolean explodesDestructively() {
return false;
}
@Override
public void explode(int cell) {
//We're blowing up, so no need for a fuse anymore.
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
super.explode(cell);
PathFinder.buildDistanceMap( cell, BArray.not( Dungeon.level.solid, null ), 2 );
for (int i = 0; i < PathFinder.distance.length; i++) {