v0.2.4: reworked bombs
This commit is contained in:
parent
e6e63ad96e
commit
8631aded20
|
@ -17,13 +17,15 @@
|
||||||
*/
|
*/
|
||||||
package com.shatteredpixel.shatteredpixeldungeon.items;
|
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.watabou.noosa.audio.Sample;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.Assets;
|
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.Buff;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis;
|
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.BlastParticle;
|
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.BlastParticle;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.SmokeParticle;
|
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.levels.Terrain;
|
||||||
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.utils.Bundle;
|
||||||
import com.watabou.utils.Random;
|
import com.watabou.utils.Random;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class Bomb extends Item {
|
public class Bomb extends Item {
|
||||||
|
|
||||||
{
|
{
|
||||||
name = "bomb";
|
name = "bomb";
|
||||||
image = ItemSpriteSheet.BOMB;
|
image = ItemSpriteSheet.BOMB;
|
||||||
defaultAction = AC_THROW;
|
defaultAction = AC_LIGHTTHROW;
|
||||||
stackable = true;
|
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<String> actions(Hero hero) {
|
||||||
|
ArrayList<String> 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 ) {
|
protected void onThrow( int cell ) {
|
||||||
if (Level.pit[cell]) {
|
if (!Level.pit[ cell ] && lightingFuse) {
|
||||||
super.onThrow( cell );
|
Actor.addDelayed(fuse = new Fuse().ignite(this), 2);
|
||||||
} else {
|
}
|
||||||
Sample.INSTANCE.play( Assets.SND_BLAST, 2 );
|
if (Actor.findChar( cell ) != null && !(Actor.findChar( cell ) instanceof Hero) ){
|
||||||
|
int newCell;
|
||||||
if (Dungeon.visible[cell]) {
|
do {
|
||||||
CellEmitter.center( cell ).burst( BlastParticle.FACTORY, 30 );
|
newCell = cell + Level.NEIGHBOURS8[Random.Int( 8 )];
|
||||||
}
|
} while (!Level.passable[newCell]);
|
||||||
|
Dungeon.level.drop( this, newCell ).sprite.drop( cell );
|
||||||
boolean terrainAffected = false;
|
} else
|
||||||
for (int n : Level.NEIGHBOURS9) {
|
super.onThrow( cell );
|
||||||
int c = cell + n;
|
}
|
||||||
if (c >= 0 && c < Level.LENGTH) {
|
|
||||||
if (Dungeon.visible[c]) {
|
@Override
|
||||||
CellEmitter.get( c ).burst( SmokeParticle.FACTORY, 4 );
|
public boolean doPickUp(Hero hero) {
|
||||||
}
|
if (fuse != null) {
|
||||||
|
GLog.w("You quickly snuff the bomb's fuse.");
|
||||||
if (Level.flamable[c]) {
|
fuse = null;
|
||||||
Level.set( c, Terrain.EMBERS );
|
}
|
||||||
GameScene.updateMap( c );
|
return super.doPickUp(hero);
|
||||||
terrainAffected = true;
|
}
|
||||||
}
|
|
||||||
|
public void explode(int cell){
|
||||||
Char ch = Actor.findChar( c );
|
//We're blowing up, so no need for a fuse anymore.
|
||||||
if (ch != null) {
|
this.fuse = null;
|
||||||
int dmg = Random.Int( 1 + Dungeon.depth, 10 + Dungeon.depth * 2 ) - Random.Int( ch.dr() );
|
|
||||||
if (dmg > 0) {
|
Sample.INSTANCE.play( Assets.SND_BLAST, 2 );
|
||||||
ch.damage( dmg, this );
|
|
||||||
if (ch.isAlive()) {
|
if (Dungeon.visible[cell]) {
|
||||||
Buff.prolong( ch, Paralysis.class, 2 );
|
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
|
@Override
|
||||||
public Item random() {
|
public Item random() {
|
||||||
quantity = Random.IntRange( 1, 3 );
|
switch(Random.Int( 2 )){
|
||||||
return this;
|
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
|
@Override
|
||||||
public int price() {
|
public int price() {
|
||||||
return 10 * quantity;
|
return 20 * quantity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String info() {
|
public String info() {
|
||||||
return
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -284,6 +284,12 @@ public class Heap implements Bundlable {
|
||||||
//stop processing current explosion, it will be replaced by the new one.
|
//stop processing current explosion, it will be replaced by the new one.
|
||||||
return;
|
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
|
//unique and upgraded items can endure the blast
|
||||||
} else if (!(item.level > 0 || item.unique))
|
} else if (!(item.level > 0 || item.unique))
|
||||||
items.remove( item );
|
items.remove( item );
|
||||||
|
@ -318,7 +324,7 @@ public class Heap implements Bundlable {
|
||||||
((Potion) item).shatter(pos);
|
((Potion) item).shatter(pos);
|
||||||
frozen = true;
|
frozen = true;
|
||||||
} else if (item instanceof Bomb){
|
} else if (item instanceof Bomb){
|
||||||
((Bomb) item).fuseLit = false;
|
((Bomb) item).fuse = null;
|
||||||
frozen = true;
|
frozen = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user