From 39a50a1dc0f3e51d4b574062ad51db809685b0d6 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Wed, 12 Jul 2023 13:02:35 -0400 Subject: [PATCH] v2.2.0: refactored noisemaker code to more cleanly extend from Bomb --- .../shatteredpixeldungeon/items/Heap.java | 3 +- .../items/bombs/Bomb.java | 36 ++-- .../items/bombs/Noisemaker.java | 170 ++++++++---------- 3 files changed, 98 insertions(+), 111 deletions(-) diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Heap.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Heap.java index 274d66d59..8ee5783ec 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Heap.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Heap.java @@ -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(); } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/bombs/Bomb.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/bombs/Bomb.java index ae28093a3..19ff91f5c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/bombs/Bomb.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/bombs/Bomb.java @@ -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 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; + } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/bombs/Noisemaker.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/bombs/Noisemaker.java index e279c8c6d..b9d1d80d7 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/bombs/Noisemaker.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/bombs/Noisemaker.java @@ -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); } }