v2.2.0: refactored noisemaker code to more cleanly extend from Bomb

This commit is contained in:
Evan Debenham
2023-07-12 13:02:35 -04:00
parent d39ecceaef
commit 39a50a1dc0
3 changed files with 98 additions and 111 deletions

View File

@@ -321,8 +321,7 @@ public class Heap implements Bundlable {
((Potion) item).shatter(pos);
frozen = true;
} else if (item instanceof Bomb){
((Bomb) item).fuse = null;
frozen = true;
frozen = frozen || ((Bomb) item).fuse.freeze();
}
}

View File

@@ -107,10 +107,14 @@ public class Bomb extends Item {
super.execute(hero, action);
}
protected Fuse createFuse(){
return new Fuse();
}
@Override
protected void onThrow( int cell ) {
if (!Dungeon.level.pit[ cell ] && lightingFuse) {
Actor.addDelayed(fuse = new Fuse().ignite(this), 2);
Actor.addDelayed(fuse = createFuse().ignite(this), 2);
}
if (Actor.findChar( cell ) != null && !(Actor.findChar( cell ) instanceof Hero) ){
ArrayList<Integer> candidates = new ArrayList<>();
@@ -269,7 +273,7 @@ public class Bomb extends Item {
actPriority = BLOB_PRIO+1; //after hero, before other actors
}
private Bomb bomb;
protected Bomb bomb;
public Fuse ignite(Bomb bomb){
this.bomb = bomb;
@@ -289,21 +293,7 @@ public class Bomb extends Item {
for (Heap heap : Dungeon.level.heaps.valueList()) {
if (heap.items.contains(bomb)) {
//FIXME this is a bit hacky, might want to generalize the functionality
//of bombs that don't explode instantly when their fuse ends
if (bomb instanceof Noisemaker){
((Noisemaker) bomb).setTrigger(heap.pos);
} else {
heap.remove(bomb);
bomb.explode(heap.pos);
}
diactivate();
Actor.remove(this);
trigger(heap);
return true;
}
}
@@ -313,6 +303,18 @@ public class Bomb extends Item {
Actor.remove( this );
return true;
}
protected void trigger(Heap heap){
heap.remove(bomb);
bomb.explode(heap.pos);
Actor.remove(this);
}
public boolean freeze(){
bomb.fuse = null;
Actor.remove(this);
return true;
}
}

View File

@@ -24,14 +24,11 @@ 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.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Bundle;
@@ -42,122 +39,111 @@ public class Noisemaker extends Bomb {
image = ItemSpriteSheet.NOISEMAKER;
}
public void setTrigger(int cell){
Buff.affect(Dungeon.hero, Trigger.class).set(cell);
fuse = null;
}
@Override
public ItemSprite.Glowing glowing() {
if (fuse == null){
for (Trigger trigger : Dungeon.hero.buffs(Trigger.class)){
Heap heap = Dungeon.level.heaps.get(trigger.cell);
if (heap != null && heap.items.contains(this)) {
return new ItemSprite.Glowing( 0xFF0000, 0.6f);
}
}
}
return super.glowing();
protected Fuse createFuse() {
return new NoisemakerFuse();
}
@Override
public boolean doPickUp(Hero hero, int pos) {
if (fuse == null){
for (Trigger trigger : hero.buffs(Trigger.class)){
if (trigger.cell == pos) return false;
}
//cannot pickup after first trigger
if (fuse instanceof NoisemakerFuse && ((NoisemakerFuse) fuse).triggered){
return false;
}
return super.doPickUp(hero, pos);
}
public static class Trigger extends Buff {
//does not instantly explode
public static class NoisemakerFuse extends Fuse {
{
revivePersists = true;
}
private boolean triggered = false;
private int left;
int cell;
int floor;
int left;
public void set(int cell){
floor = Dungeon.depth;
this.cell = cell;
left = 0;
}
@Override
public boolean act() {
protected boolean act() {
if (!triggered){
//acts like a normal fuse until first trigger
return super.act();
} else {
if (Dungeon.depth != floor){
spend(TICK);
for (Heap heap : Dungeon.level.heaps.valueList()) {
if (heap.items.contains(bomb)) {
//active noisemakers cannot be snuffed out, blow it up!
if (bomb.fuse != this){
trigger(heap);
//check if there is a nearby char, blow up if there is
} else if (Actor.findChar(heap.pos) != null) {
heap.items.remove(bomb);
if (heap.items.isEmpty()) {
heap.destroy();
}
trigger(heap);
//otherwise tick down our counter to alert
} else {
spend(TICK);
left--;
if (left <= 0){
CellEmitter.center( heap.pos ).start( Speck.factory( Speck.SCREAM ), 0.3f, 3 );
Sample.INSTANCE.play( Assets.Sounds.ALERT );
for (Mob mob : Dungeon.level.mobs.toArray( new Mob[0] )) {
mob.beckon( heap.pos );
}
left = 6;
}
}
return true;
}
}
//can't find our bomb, something must have removed it, do nothing.
bomb.fuse = null;
Actor.remove( this );
return true;
}
Noisemaker bomb = null;
Heap heap = Dungeon.level.heaps.get(cell);
if (heap != null){
for (Item i : heap.items){
if (i instanceof Noisemaker){
bomb = (Noisemaker) i;
break;
}
}
}
if (bomb == null) {
detach();
} else if (Actor.findChar(cell) != null) {
heap.items.remove(bomb);
if (heap.items.isEmpty()) {
heap.destroy();
}
detach();
bomb.explode(cell);
} else {
spend(TICK);
left--;
if (left <= 0){
CellEmitter.center( cell ).start( Speck.factory( Speck.SCREAM ), 0.3f, 3 );
Sample.INSTANCE.play( Assets.Sounds.ALERT );
for (Mob mob : Dungeon.level.mobs.toArray( new Mob[0] )) {
mob.beckon( cell );
}
left = 6;
}
}
return true;
}
private static final String CELL = "cell";
private static final String FLOOR = "floor";
@Override
//first trigger sets the alarm mechanism, second explodes
protected void trigger(Heap heap) {
if (!triggered) {
triggered = true;
} else {
super.trigger(heap);
}
}
@Override
public boolean freeze() {
if (!triggered) {
return super.freeze();
} else {
//noisemakers cannot have their fuse snuffed once triggered
return false;
}
}
private static final String LEFT = "left";
@Override
public void storeInBundle(Bundle bundle) {
super.storeInBundle(bundle);
bundle.put(CELL, cell);
bundle.put(FLOOR, floor);
bundle.put(LEFT, left);
}
@Override
public void restoreFromBundle(Bundle bundle) {
super.restoreFromBundle(bundle);
cell = bundle.getInt(CELL);
floor = bundle.getInt(FLOOR);
left = bundle.getInt(LEFT);
}
}