From 8631aded209b225211bef3db2dc14ff6363ff0fc Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Mon, 16 Feb 2015 05:01:24 -0500 Subject: [PATCH] v0.2.4: reworked bombs --- .../shatteredpixeldungeon/items/Bomb.java | 248 ++++++++++++++---- .../shatteredpixeldungeon/items/Heap.java | 8 +- 2 files changed, 208 insertions(+), 48 deletions(-) diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/items/Bomb.java b/src/com/shatteredpixel/shatteredpixeldungeon/items/Bomb.java index be5dae34b..6fe5d06b0 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/items/Bomb.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/items/Bomb.java @@ -17,13 +17,15 @@ */ package com.shatteredpixel.shatteredpixeldungeon.items; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite; +import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; +import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.watabou.noosa.audio.Sample; 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.Buff; -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis; import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.BlastParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.SmokeParticle; @@ -31,58 +33,119 @@ import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.watabou.utils.Bundle; import com.watabou.utils.Random; +import java.util.ArrayList; + public class Bomb extends Item { { name = "bomb"; image = ItemSpriteSheet.BOMB; - defaultAction = AC_THROW; + defaultAction = AC_LIGHTTHROW; stackable = true; } - - @Override + + public Fuse fuse; + + //FIXME using a static variable for this is kinda gross, should be a better way + private static boolean lightingFuse = false; + + private static final String AC_LIGHTTHROW = "Light & Throw"; + + @Override + public boolean isSimilar(Item item) { + return item instanceof Bomb && this.fuse == ((Bomb) item).fuse; + } + + @Override + public ArrayList actions(Hero hero) { + ArrayList actions = super.actions( hero ); + actions.add ( AC_LIGHTTHROW ); + return actions; + } + + @Override + public void execute(Hero hero, String action) { + if (action.equals( AC_LIGHTTHROW )){ + lightingFuse = true; + action = AC_THROW; + } else + lightingFuse = false; + + super.execute(hero, action); + } + + @Override protected void onThrow( int cell ) { - if (Level.pit[cell]) { - super.onThrow( cell ); - } else { - Sample.INSTANCE.play( Assets.SND_BLAST, 2 ); - - if (Dungeon.visible[cell]) { - CellEmitter.center( cell ).burst( BlastParticle.FACTORY, 30 ); - } - - boolean terrainAffected = false; - for (int n : Level.NEIGHBOURS9) { - int c = cell + n; - if (c >= 0 && c < Level.LENGTH) { - if (Dungeon.visible[c]) { - CellEmitter.get( c ).burst( SmokeParticle.FACTORY, 4 ); - } - - if (Level.flamable[c]) { - Level.set( c, Terrain.EMBERS ); - GameScene.updateMap( c ); - terrainAffected = true; - } - - Char ch = Actor.findChar( c ); - if (ch != null) { - int dmg = Random.Int( 1 + Dungeon.depth, 10 + Dungeon.depth * 2 ) - Random.Int( ch.dr() ); - if (dmg > 0) { - ch.damage( dmg, this ); - if (ch.isAlive()) { - Buff.prolong( ch, Paralysis.class, 2 ); - } - } + if (!Level.pit[ cell ] && lightingFuse) { + Actor.addDelayed(fuse = new Fuse().ignite(this), 2); + } + if (Actor.findChar( cell ) != null && !(Actor.findChar( cell ) instanceof Hero) ){ + int newCell; + do { + newCell = cell + Level.NEIGHBOURS8[Random.Int( 8 )]; + } while (!Level.passable[newCell]); + Dungeon.level.drop( this, newCell ).sprite.drop( cell ); + } else + super.onThrow( cell ); + } + + @Override + public boolean doPickUp(Hero hero) { + if (fuse != null) { + GLog.w("You quickly snuff the bomb's fuse."); + fuse = null; + } + return super.doPickUp(hero); + } + + 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, 2 ); + + if (Dungeon.visible[cell]) { + CellEmitter.center( cell ).burst( BlastParticle.FACTORY, 30 ); + } + + boolean terrainAffected = false; + for (int n : Level.NEIGHBOURS9) { + int c = cell + n; + if (c >= 0 && c < Level.LENGTH) { + if (Dungeon.visible[c]) { + CellEmitter.get( c ).burst( SmokeParticle.FACTORY, 4 ); + } + + if (Level.flamable[c]) { + Level.set( c, Terrain.EMBERS ); + GameScene.updateMap( c ); + terrainAffected = true; + } + + 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 ) - Random.Int( ch.dr() ); + if (dmg > 0) { + ch.damage( dmg, this ); } } + + //destroys items / triggers bombs caught in the blast. + Heap heap = Dungeon.level.heaps.get( c ); + if(heap != null) + heap.explode(); } - - if (terrainAffected) { - Dungeon.observe(); - } + } + + if (terrainAffected) { + Dungeon.observe(); } } @@ -98,18 +161,109 @@ public class Bomb extends Item { @Override public Item random() { - quantity = Random.IntRange( 1, 3 ); - return this; - } - + switch(Random.Int( 2 )){ + case 0: + default: + return this; + case 1: + return new DoubleBomb(); + } + } + + @Override + public ItemSprite.Glowing glowing() { + return fuse != null ? new ItemSprite.Glowing( 0xFF0000, 0.6f) : null; + } + @Override public int price() { - return 10 * quantity; + return 20 * quantity; } @Override public String info() { return - "This is a relatively small bomb, filled with black powder. Conveniently, its fuse is lit automatically when the bomb is thrown."; + "A fairly hefty black powder bomb. An explosion from this would certainly do damage to anything nearby." + + (fuse != null ? "\n\nThe bomb's fuse is burning away, keep your distance or put it out!" : + "\n\nIt looks like the fuse will take a couple rounds to burn down once it is lit."); + } + + private static final String FUSE = "fuse"; + + @Override + public void storeInBundle(Bundle bundle) { + super.storeInBundle(bundle); + bundle.put( FUSE, fuse ); + } + + @Override + public void restoreFromBundle(Bundle bundle) { + super.restoreFromBundle(bundle); + if (bundle.contains( FUSE )) + Actor.add( fuse = ((Fuse)bundle.get(FUSE)).ignite(this) ); + } + + + public static class Fuse extends Actor{ + + private Bomb bomb; + + public Fuse ignite(Bomb bomb){ + this.bomb = bomb; + return this; + } + + @Override + protected boolean act() { + + //something caused our bomb to explode early, or be defused. Do nothing. + if (bomb.fuse != this){ + Actor.remove( this ); + return true; + } + + //look for our bomb, remove it from its heap, and blow it up. + for (Heap heap : Dungeon.level.heaps.values()) { + if (heap.items.contains(bomb)) { + heap.items.remove(bomb); + + bomb.explode(heap.pos); + + Actor.remove(this); + return true; + } + } + + //can't find our bomb, this should never happen, throw an exception. + throw new RuntimeException("Something caused a lit bomb to not be present in a heap on the level!"); + } + } + + + public static class DoubleBomb extends Bomb{ + + { + name = "two bombs"; + image = ItemSpriteSheet.DBL_BOMB; + stackable = false; + } + + @Override + public String info() { + return + "A stack of two hefty black powder bombs, looks like you get one free!"; + } + + @Override + public boolean doPickUp(Hero hero) { + Bomb bomb = new Bomb(); + bomb.quantity(2); + if (bomb.doPickUp(hero)) { + //isaaaaac.... + hero.sprite.showStatus(CharSprite.NEUTRAL, "1+1 free!"); + return true; + } + return false; + } } } diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/items/Heap.java b/src/com/shatteredpixel/shatteredpixeldungeon/items/Heap.java index 10f5fa5ab..2c586c177 100644 --- a/src/com/shatteredpixel/shatteredpixeldungeon/items/Heap.java +++ b/src/com/shatteredpixel/shatteredpixeldungeon/items/Heap.java @@ -284,6 +284,12 @@ public class Heap implements Bundlable { //stop processing current explosion, it will be replaced by the new one. return; + } else if (item instanceof Honeypot.ShatteredPot){ + + //need to let the bee know the pot is being destroyed. + ((Honeypot.ShatteredPot) item).goAway(); + items.remove( item ); + //unique and upgraded items can endure the blast } else if (!(item.level > 0 || item.unique)) items.remove( item ); @@ -318,7 +324,7 @@ public class Heap implements Bundlable { ((Potion) item).shatter(pos); frozen = true; } else if (item instanceof Bomb){ - ((Bomb) item).fuseLit = false; + ((Bomb) item).fuse = null; frozen = true; } }