v0.8.1: Potion of dragon's breath now uses the new cone AOE logic

This commit is contained in:
Evan Debenham 2020-06-22 20:04:19 -04:00
parent 148fc96d91
commit 804a6a88a9

View File

@ -33,6 +33,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Cripple;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile; import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.ConeAOE;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector; import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
@ -48,20 +49,12 @@ public class PotionOfDragonsBreath extends ExoticPotion {
{ {
icon = ItemSpriteSheet.Icons.POTION_DRGBREATH; icon = ItemSpriteSheet.Icons.POTION_DRGBREATH;
} }
//a lot of this is copy-paste from wand of fireblast
//the actual affected cells
private HashSet<Integer> affectedCells;
//the cells to trace fire shots to, for visual effects.
private HashSet<Integer> visualCells;
private int direction = 0;
@Override @Override
//need to override drink so that time isn't spent right away //need to override drink so that time isn't spent right away
protected void drink(final Hero hero) { protected void drink(final Hero hero) {
curItem = detach( hero.belongings.backpack ); curUser = hero;
setKnown(); curItem = this;
GameScene.selectCell(targeter); GameScene.selectCell(targeter);
} }
@ -69,58 +62,37 @@ public class PotionOfDragonsBreath extends ExoticPotion {
private CellSelector.Listener targeter = new CellSelector.Listener() { private CellSelector.Listener targeter = new CellSelector.Listener() {
@Override @Override
public void onSelect(final Integer cell) { public void onSelect(final Integer cell) {
if (cell == null){ if (cell == null && !isKnown()){
//TODO if this can ever be found un-IDed, need logic for that setKnown();
curItem.collect(); detach(curUser.belongings.backpack);
} else { } else if (cell != null) {
setKnown();
Sample.INSTANCE.play( Assets.Sounds.DRINK ); Sample.INSTANCE.play( Assets.Sounds.DRINK );
curUser.sprite.operate(curUser.pos, new Callback() { curUser.sprite.operate(curUser.pos, new Callback() {
@Override @Override
public void call() { public void call() {
curItem.detach(curUser.belongings.backpack);
curUser.spend(1f); curUser.spend(1f);
curUser.sprite.idle(); curUser.sprite.idle();
curUser.sprite.zap(cell); curUser.sprite.zap(cell);
Sample.INSTANCE.play( Assets.Sounds.BURNING );
final Ballistica bolt
= new Ballistica(curUser.pos, cell, Ballistica.MAGIC_BOLT); final Ballistica bolt = new Ballistica(curUser.pos, cell, Ballistica.STOP_TERRAIN);
affectedCells = new HashSet<>();
visualCells = new HashSet<>();
int maxDist = 6; int maxDist = 6;
int dist = Math.min(bolt.dist, maxDist); int dist = Math.min(bolt.dist, maxDist);
for (int i = 0; i < PathFinder.CIRCLE8.length; i++) { final ConeAOE cone = new ConeAOE(curUser.pos, bolt.path.get(dist), 6, 60, Ballistica.STOP_TERRAIN | Ballistica.STOP_TARGET );
if (bolt.sourcePos + PathFinder.CIRCLE8[i] == bolt.path.get(1)) {
direction = i; //cast to cells at the tip, rather than all cells, better performance.
break; for (Ballistica ray : cone.rays){
} ((MagicMissile)curUser.sprite.parent.recycle( MagicMissile.class )).reset(
}
float strength = maxDist;
for (int c : bolt.subPath(1, dist)) {
strength--; //as we start at dist 1, not 0.
affectedCells.add(c);
if (strength > 1) {
spreadFlames(c + PathFinder.CIRCLE8[left(direction)], strength - 1);
spreadFlames(c + PathFinder.CIRCLE8[direction], strength - 1);
spreadFlames(c + PathFinder.CIRCLE8[right(direction)], strength - 1);
} else {
visualCells.add(c);
}
}
//going to call this one manually
visualCells.remove(bolt.path.get(dist));
for (int c : visualCells) {
//this way we only get the cells at the tip, much better performance.
((MagicMissile) curUser.sprite.parent.recycle(MagicMissile.class)).reset(
MagicMissile.FIRE_CONE, MagicMissile.FIRE_CONE,
curUser.sprite, curUser.sprite,
c, ray.path.get(ray.dist),
null null
); );
} }
@ -132,21 +104,25 @@ public class PotionOfDragonsBreath extends ExoticPotion {
new Callback() { new Callback() {
@Override @Override
public void call() { public void call() {
for (int cell : affectedCells){ for (int cell : cone.cells){
//ignore caster cell //ignore caster cell
if (cell == bolt.sourcePos){ if (cell == bolt.sourcePos){
continue; continue;
} }
GameScene.add( Blob.seed( cell, 5, Fire.class ) ); //only ignite cells directly near caster if they are flammable
if (!Dungeon.level.adjacent(bolt.sourcePos, cell) || Dungeon.level.flamable[cell]){
GameScene.add( Blob.seed( cell, 5, Fire.class ) );
}
Char ch = Actor.findChar( cell ); Char ch = Actor.findChar( cell );
if (ch != null) { if (ch != null) {
Buff.affect( ch, Burning.class ).reignite( ch ); Buff.affect( ch, Burning.class ).reignite( ch );
Buff.affect(ch, Cripple.class, 5f); break; Buff.affect(ch, Cripple.class, 5f);
} }
} }
curUser.next();
} }
}); });
@ -160,29 +136,4 @@ public class PotionOfDragonsBreath extends ExoticPotion {
return Messages.get(PotionOfDragonsBreath.class, "prompt"); return Messages.get(PotionOfDragonsBreath.class, "prompt");
} }
}; };
//burn... BURNNNNN!.....
private void spreadFlames(int cell, float strength){
if (strength >= 0 && (Dungeon.level.passable[cell] || Dungeon.level.flamable[cell])){
affectedCells.add(cell);
if (strength >= 1.5f) {
visualCells.remove(cell);
spreadFlames(cell + PathFinder.CIRCLE8[left(direction)], strength - 1.5f);
spreadFlames(cell + PathFinder.CIRCLE8[direction], strength - 1.5f);
spreadFlames(cell + PathFinder.CIRCLE8[right(direction)], strength - 1.5f);
} else {
visualCells.add(cell);
}
} else if (!Dungeon.level.passable[cell])
visualCells.add(cell);
}
private int left(int direction){
return direction == 0 ? 7 : direction-1;
}
private int right(int direction){
return direction == 7 ? 0 : direction+1;
}
} }