diff --git a/src/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfBlastWave.java b/src/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfBlastWave.java new file mode 100644 index 000000000..f5cf7e128 --- /dev/null +++ b/src/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfBlastWave.java @@ -0,0 +1,179 @@ +package com.shatteredpixel.shatteredpixeldungeon.items.wands; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.DungeonTilemap; +import com.shatteredpixel.shatteredpixeldungeon.ResultDescriptions; +import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis; +import com.shatteredpixel.shatteredpixeldungeon.effects.Effects; +import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile; +import com.shatteredpixel.shatteredpixeldungeon.effects.Pushing; +import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff; +import com.shatteredpixel.shatteredpixeldungeon.levels.Level; +import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; +import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; +import com.shatteredpixel.shatteredpixeldungeon.utils.Utils; +import com.watabou.noosa.Game; +import com.watabou.noosa.Group; +import com.watabou.noosa.Image; +import com.watabou.noosa.audio.Sample; +import com.watabou.utils.Callback; +import com.watabou.utils.Random; + +/** + * Created by debenhame on 05/05/2015. + */ +public class WandOfBlastWave extends Wand { + + { + name = "Wand of Blast Wave"; + image = ItemSpriteSheet.WAND_BLAST_WAVE; + + collisionProperties = Ballistica.PROJECTILE; + } + + @Override + protected void onZap(Ballistica bolt) { + Sample.INSTANCE.play( Assets.SND_BLAST ); + BlastWave.blast(bolt.collisionPos); + + int damage = Random.NormalIntRange(1, 6+(int)(level*level/4f)); + + //presses all tiles in the AOE first + for (int i : Level.NEIGHBOURS9){ + Dungeon.level.press(bolt.collisionPos+i, Actor.findChar(bolt.collisionPos+i)); + } + + //throws other chars around the center. + for (int i : Level.NEIGHBOURS8){ + Char ch = Actor.findChar(bolt.collisionPos + i); + + if (ch != null){ + ch.damage(damage, this); + + if (ch.isAlive()) { + Ballistica trajectory = new Ballistica(ch.pos, ch.pos + i, Ballistica.MAGIC_BOLT); + int strength = 1 + ((level + 1) / 3); + throwChar(ch, trajectory, strength); + } + } + } + + //throws the char at the center of the blast + Char ch = Actor.findChar(bolt.collisionPos); + if (ch != null){ + ch.damage(damage, this); + + if (ch.isAlive() && bolt.path.size() > bolt.dist) { + Ballistica trajectory = new Ballistica(ch.pos, bolt.path.get(bolt.dist + 1), Ballistica.MAGIC_BOLT); + int strength = level + 3; + throwChar(ch, trajectory, strength); + } + } + + if (!curUser.isAlive()) { + Dungeon.fail( Utils.format(ResultDescriptions.ITEM, name) ); + GLog.n("You killed yourself with your own Wand of Blast Wave..."); + } + } + + private void throwChar(Char ch, Ballistica trajectory, int power){ + int dist = Math.min(trajectory.dist, power); + + if (dist == 0) return; + + int newPos = trajectory.path.get(dist); + + if (Actor.findChar(newPos) != null){ + newPos = trajectory.path.get(--dist); + } + + if (newPos == ch.pos) return; + + + Actor.addDelayed(new Pushing(ch, ch.pos, newPos), -1); + ch.pos = newPos; + Dungeon.level.press(newPos, ch); + + if (ch.pos == trajectory.collisionPos) { + ch.damage(Random.NormalIntRange((dist + 1) / 2, dist), this); + Paralysis.prolong(ch, Paralysis.class, Random.NormalIntRange((dist + 1) / 2, dist)); + } + + } + + @Override + //a weaker knockback, not dissimilar to the glyph of bounce, but a fair bit stronger. + public void onHit(MagesStaff staff, Char attacker, Char defender, int damage) { + int level = Math.max(0, staff.level); + + // lvl 0 - 25% + // lvl 1 - 40% + // lvl 2 - 50% + if (Random.Int( level + 4 ) >= 3){ + int oppositeHero = defender.pos + (defender.pos - attacker.pos); + Ballistica trajectory = new Ballistica(defender.pos, oppositeHero, Ballistica.MAGIC_BOLT); + throwChar(defender, trajectory, 2); + } + } + + @Override + protected void fx(Ballistica bolt, Callback callback) { + MagicMissile.slowness(curUser.sprite.parent, bolt.sourcePos, bolt.collisionPos, callback); + Sample.INSTANCE.play(Assets.SND_ZAP); + } + + public static class BlastWave extends Image { + + private static final float TIME_TO_FADE = 0.2f; + + private float time; + + public BlastWave(){ + super(Effects.get(Effects.Type.RIPPLE)); + origin.set(width / 2, height / 2); + } + + public void reset(int pos) { + revive(); + + x = (pos % Level.WIDTH) * DungeonTilemap.SIZE + (DungeonTilemap.SIZE - width) / 2; + y = (pos / Level.WIDTH) * DungeonTilemap.SIZE + (DungeonTilemap.SIZE - height) / 2; + + time = TIME_TO_FADE; + } + + @Override + public void update() { + super.update(); + + if ((time -= Game.elapsed) <= 0) { + kill(); + } else { + float p = time / TIME_TO_FADE; + alpha(p); + scale.y = scale.x = (1-p)*3; + } + } + + public static void blast(int pos) { + Group parent = Dungeon.hero.sprite.parent; + BlastWave b = (BlastWave) parent.recycle(BlastWave.class); + parent.bringToFront(b); + b.reset(pos); + } + + } + + @Override + public String desc() { + return "This wand is made of a sort of marbled stone, with gold trim and a round black gem at the tip. " + + "It feels very weighty in your hand.\n" + + "\n" + + "This wand shoots a bolt which violently detonates at a target location. There is no smoke and fire, " + + "but the force of this blast is enough to knock even the biggest of foes around."; + } +}