v3.3.4: arcane bombs no longer use blobs for vfx

This commit is contained in:
Evan Debenham
2026-01-19 13:00:32 -05:00
parent a467a5ea4a
commit c9c2f73c9a
3 changed files with 69 additions and 19 deletions

View File

@@ -30,7 +30,7 @@ import com.shatteredpixel.shatteredpixeldungeon.sprites.GooSprite;
public class GooWarn extends Blob {
//cosmetic blob, previously used for Goo's pump up attack (that's now handled by Goo's sprite)
// but is still used as a visual indicator for Arcane bombs
// as of v3.3.4 it's not longer used by arcane bomb either
{
//this one needs to act just before the Goo

View File

@@ -23,15 +23,21 @@ package com.shatteredpixel.shatteredpixeldungeon.items.bombs;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.GooWarn;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle;
import com.shatteredpixel.shatteredpixeldungeon.items.Heap;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.GooSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.noosa.Game;
import com.watabou.noosa.particles.Emitter;
import com.watabou.utils.BArray;
import com.watabou.utils.Callback;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Random;
@@ -54,18 +60,10 @@ public class ArcaneBomb extends Bomb {
}
@Override
protected void onThrow(int cell) {
super.onThrow(cell);
if (fuse != null){
PathFinder.buildDistanceMap( cell, BArray.not( Dungeon.level.solid, null ), explosionRange() );
for (int i = 0; i < PathFinder.distance.length; i++) {
if (PathFinder.distance[i] < Integer.MAX_VALUE) {
GameScene.add(Blob.seed(i, 3, GooWarn.class));
}
}
}
protected Fuse createFuse() {
return new ArcaneBombFuse();
}
@Override
public void explode(int cell) {
super.explode(cell);
@@ -75,9 +73,7 @@ public class ArcaneBomb extends Bomb {
PathFinder.buildDistanceMap( cell, BArray.not( Dungeon.level.solid, null ), explosionRange() );
for (int i = 0; i < PathFinder.distance.length; i++) {
if (PathFinder.distance[i] < Integer.MAX_VALUE) {
if (Dungeon.level.heroFOV[i]) {
CellEmitter.get(i).burst(ElmoParticle.FACTORY, 10);
}
CellEmitter.get(i).burst(ElmoParticle.FACTORY, 10);
Char ch = Actor.findChar(i);
if (ch != null){
affected.add(ch);
@@ -101,4 +97,52 @@ public class ArcaneBomb extends Bomb {
//prices of ingredients
return quantity * (20 + 30);
}
//normal fuse logic, but with particle effects
public static class ArcaneBombFuse extends Fuse {
private ArrayList<Emitter> gooWarnEmitters = new ArrayList<>();
//particle effect addition is delayed using an actor to ensure things like gamescene is set up when loading
@Override
public Fuse ignite(Bomb bomb) {
super.ignite(bomb);
Actor.add(new Actor() {
{ actPriority = VFX_PRIO; }
@Override
protected boolean act() {
int bombPos = -1;
for (Heap heap : Dungeon.level.heaps.valueList()) {
if (heap.items.contains(bomb)) {
bombPos = heap.pos;
}
}
if (bombPos != -1) {
PathFinder.buildDistanceMap(bombPos, BArray.not(Dungeon.level.solid, null), bomb.explosionRange());
for (int i = 0; i < PathFinder.distance.length; i++) {
if (PathFinder.distance[i] < Integer.MAX_VALUE) {
Emitter e = CellEmitter.get(i);
if (e != null) {
e.pour(GooSprite.GooParticle.FACTORY, 0.03f);
gooWarnEmitters.add(e);
}
}
}
}
Actor.remove(this);
return true;
}
});
return this;
}
@Override
public void snuff() {
super.snuff();
for (Emitter e : gooWarnEmitters) {
e.on = false;
}
gooWarnEmitters.clear();
}
}
}

View File

@@ -129,6 +129,7 @@ public class Bomb extends Item {
public boolean doPickUp(Hero hero, int pos) {
if (fuse != null) {
GLog.w( Messages.get(this, "snuff_fuse") );
fuse.snuff();
fuse = null;
}
return super.doPickUp(hero, pos);
@@ -136,6 +137,7 @@ public class Bomb extends Item {
public void explode(int cell){
//We're blowing up, so no need for a fuse anymore.
fuse.snuff();
this.fuse = null;
Sample.INSTANCE.play( Assets.Sounds.BLAST );
@@ -288,7 +290,7 @@ public class Bomb extends Item {
//something caused our bomb to explode early, or be defused. Do nothing.
if (bomb.fuse != this){
Actor.remove( this );
snuff();
return true;
}
@@ -303,7 +305,7 @@ public class Bomb extends Item {
//can't find our bomb, something must have removed it, do nothing.
bomb.fuse = null;
Actor.remove( this );
snuff();
return true;
}
@@ -311,14 +313,18 @@ public class Bomb extends Item {
heap.remove(bomb);
Catalog.countUse(bomb.getClass());
bomb.explode(heap.pos);
Actor.remove(this);
snuff();
}
public boolean freeze(){
bomb.fuse = null;
Actor.remove(this);
snuff();
return true;
}
public void snuff(){
Actor.remove( this );
}
}