v0.5.0: fixed many vfx alignment issues

This commit is contained in:
Evan Debenham 2017-01-04 19:09:54 -05:00
parent cc2b0a0cb8
commit 26daff58b2
28 changed files with 383 additions and 244 deletions

View File

@ -148,6 +148,14 @@ public class Visual extends Gizmo {
return p; return p;
} }
//returns the point needed to center the argument visual on this visual
public PointF center( Visual v ) {
return new PointF(
x + (width() - v.width())/2f,
y + (height() - v.height())/2f
);
}
public float width() { public float width() {
return width * scale.x; return width * scale.x;
} }

View File

@ -45,7 +45,7 @@ public class WaterOfAwareness extends WellWater {
protected boolean affectHero( Hero hero ) { protected boolean affectHero( Hero hero ) {
Sample.INSTANCE.play( Assets.SND_DRINK ); Sample.INSTANCE.play( Assets.SND_DRINK );
emitter.parent.add( new Identification( DungeonTilemap.tileCenterToWorld( pos ) ) ); emitter.parent.add( new Identification( hero.sprite.center() ) );
hero.belongings.observe(); hero.belongings.observe();

View File

@ -108,7 +108,7 @@ public class Guard extends Mob {
} else { } else {
final int newPosFinal = newPos; final int newPosFinal = newPos;
yell( Messages.get(this, "scorpion") ); yell( Messages.get(this, "scorpion") );
sprite.parent.add(new Chains(pos, enemy.pos, new Callback() { sprite.parent.add(new Chains(sprite.center(), enemy.sprite.center(), new Callback() {
public void call() { public void call() {
Actor.addDelayed(new Pushing(enemy, enemy.pos, newPosFinal, new Callback(){ Actor.addDelayed(new Pushing(enemy, enemy.pos, newPosFinal, new Callback(){
public void call() { public void call() {

View File

@ -49,6 +49,18 @@ public class Lightning extends Group {
this(Arrays.asList(new Arc(from, to)), callback); this(Arrays.asList(new Arc(from, to)), callback);
} }
public Lightning(PointF from, int to, Callback callback){
this(Arrays.asList(new Arc(from, to)), callback);
}
public Lightning(int from, PointF to, Callback callback){
this(Arrays.asList(new Arc(from, to)), callback);
}
public Lightning(PointF from, PointF to, Callback callback){
this(Arrays.asList(new Arc(from, to)), callback);
}
public Lightning( List<Arc> arcs, Callback callback ) { public Lightning( List<Arc> arcs, Callback callback ) {
super(); super();
@ -104,8 +116,21 @@ public class Lightning extends Group {
private PointF start, end; private PointF start, end;
public Arc(int from, int to){ public Arc(int from, int to){
start = DungeonTilemap.tileCenterToWorld(from); this( DungeonTilemap.tileCenterToWorld(from),
end = DungeonTilemap.tileCenterToWorld(to); DungeonTilemap.tileCenterToWorld(to));
}
public Arc(PointF from, int to){
this( from, DungeonTilemap.tileCenterToWorld(to));
}
public Arc(int from, PointF to){
this( DungeonTilemap.tileCenterToWorld(from), to);
}
public Arc(PointF from, PointF to){
start = from;
end = to;
arc1 = new Image(Effects.get(Effects.Type.LIGHTNING)); arc1 = new Image(Effects.get(Effects.Type.LIGHTNING));
arc1.x = start.x - arc1.origin.x; arc1.x = start.x - arc1.origin.x;
@ -116,7 +141,6 @@ public class Lightning extends Group {
arc2 = new Image(Effects.get(Effects.Type.LIGHTNING)); arc2 = new Image(Effects.get(Effects.Type.LIGHTNING));
arc2.origin.set( 0, arc2.height()/2 ); arc2.origin.set( 0, arc2.height()/2 );
add( arc2 ); add( arc2 );
} }
public void alpha(float alpha) { public void alpha(float alpha) {

View File

@ -20,6 +20,7 @@
*/ */
package com.shatteredpixel.shatteredpixeldungeon.effects; package com.shatteredpixel.shatteredpixeldungeon.effects;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap; import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.FlameParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.FlameParticle;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.LeafParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.LeafParticle;
@ -30,6 +31,7 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.WoolParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.WoolParticle;
import com.watabou.noosa.Game; import com.watabou.noosa.Game;
import com.watabou.noosa.Group; import com.watabou.noosa.Group;
import com.watabou.noosa.Visual;
import com.watabou.noosa.particles.Emitter; import com.watabou.noosa.particles.Emitter;
import com.watabou.noosa.particles.PixelParticle; import com.watabou.noosa.particles.PixelParticle;
import com.watabou.utils.Callback; import com.watabou.utils.Callback;
@ -47,28 +49,101 @@ public class MagicMissile extends Emitter {
private float sy; private float sy;
private float time; private float time;
public void reset( int from, int to, Callback callback ) { //missile types
reset( from, to, SPEED, callback ); public static final int MAGIC_MISSILE = 0;
public static final int FROST = 1;
public static final int FIRE = 2;
public static final int POISON = 3;
public static final int FOLIAGE = 4;
public static final int FORCE = 5;
public static final int BEACON = 6;
public static final int SHADOW = 7;
public static final int RAINBOW = 8;
public static final int FIRE_CONE = 100;
public static final int FOLIAGE_CONE = 101;
public void reset( int type, int from, int to, Callback callback ) {
reset( type,
DungeonTilemap.tileCenterToWorld( from ),
DungeonTilemap.tileCenterToWorld( to ),
callback );
} }
public void reset( int from, int to, float velocity, Callback callback ) { public void reset( int type, Visual from, Visual to, Callback callback ) {
reset( type,
from.center(),
to.center(),
callback);
}
public void reset( int type, Visual from, int to, Callback callback ) {
reset( type,
from.center(),
DungeonTilemap.tileCenterToWorld( to ),
callback);
}
public void reset( int type, PointF from, PointF to, Callback callback ) {
this.callback = callback; this.callback = callback;
revive(); revive();
PointF pf = DungeonTilemap.tileCenterToWorld( from ); x = from.x;
PointF pt = DungeonTilemap.tileCenterToWorld( to ); y = from.y;
x = pf.x;
y = pf.y;
width = 0; width = 0;
height = 0; height = 0;
PointF d = PointF.diff( pt, pf ); PointF d = PointF.diff( to, from );
PointF speed = new PointF( d ).normalize().scale( velocity ); PointF speed = new PointF( d ).normalize().scale( SPEED );
sx = speed.x; sx = speed.x;
sy = speed.y; sy = speed.y;
time = d.length() / velocity; time = d.length() / SPEED;
switch(type){
case MAGIC_MISSILE: default:
size( 4 );
pour( WhiteParticle.FACTORY, 0.01f );
break;
case FROST:
pour( MagicParticle.FACTORY, 0.01f );
break;
case FIRE:
size( 4 );
pour( FlameParticle.FACTORY, 0.01f );
break;
case POISON:
size( 3 );
pour( PoisonParticle.MISSILE, 0.01f );
break;
case FOLIAGE:
size( 4 );
pour( LeafParticle.GENERAL, 0.01f );
break;
case FORCE:
pour( SlowParticle.FACTORY, 0.01f );
break;
case BEACON:
pour( ForceParticle.FACTORY, 0.01f );
break;
case SHADOW:
size( 4 );
pour( ShadowParticle.MISSILE, 0.01f );
break;
case RAINBOW:
size( 4 );
pour( RainbowParticle.BURST, 0.01f );
break;
case FIRE_CONE:
size( 10 );
pour( FlameParticle.FACTORY, 0.03f );
break;
case FOLIAGE_CONE:
size( 10 );
pour( LeafParticle.GENERAL, 0.03f );
break;
}
} }
public void size( float size ) { public void size( float size ) {
@ -77,93 +152,14 @@ public class MagicMissile extends Emitter {
width = height = size; width = height = size;
} }
public static void blueLight( Group group, int from, int to, Callback callback ) { //convenience method for the common case of a bolt going from a character to a tile or enemy
public static void boltFromChar(Group group, int type, Visual sprite, int to, Callback callback){
MagicMissile missile = ((MagicMissile)group.recycle( MagicMissile.class )); MagicMissile missile = ((MagicMissile)group.recycle( MagicMissile.class ));
missile.reset( from, to, callback ); if (Actor.findChar(to) != null){
missile.pour( MagicParticle.FACTORY, 0.01f ); missile.reset(type, sprite, Actor.findChar(to).sprite, callback);
} else {
missile.reset(type, sprite, to, callback);
} }
public static void fire( Group group, int from, int to, Callback callback ) {
MagicMissile missile = ((MagicMissile)group.recycle( MagicMissile.class ));
missile.reset( from, to, callback );
missile.size( 10 );
missile.pour( FlameParticle.FACTORY, 0.03f );
}
public static void earth( Group group, int from, int to, Callback callback ) {
MagicMissile missile = ((MagicMissile)group.recycle( MagicMissile.class ));
missile.reset( from, to, callback );
missile.size( 2 );
missile.pour( EarthParticle.FACTORY, 0.01f );
}
public static void purpleLight( Group group, int from, int to, Callback callback ) {
MagicMissile missile = ((MagicMissile)group.recycle( MagicMissile.class ));
missile.reset( from, to, callback );
missile.size( 2 );
missile.pour( PurpleParticle.MISSILE, 0.01f );
}
public static void whiteLight( Group group, int from, int to, Callback callback ) {
MagicMissile missile = ((MagicMissile)group.recycle( MagicMissile.class ));
missile.reset( from, to, callback );
missile.size( 4 );
missile.pour( WhiteParticle.FACTORY, 0.01f );
}
public static void wool( Group group, int from, int to, Callback callback ) {
MagicMissile missile = ((MagicMissile)group.recycle( MagicMissile.class ));
missile.reset( from, to, callback );
missile.size( 3 );
missile.pour( WoolParticle.FACTORY, 0.01f );
}
public static void poison( Group group, int from, int to, Callback callback ) {
MagicMissile missile = ((MagicMissile)group.recycle( MagicMissile.class ));
missile.reset( from, to, callback );
missile.size( 3 );
missile.pour( PoisonParticle.MISSILE, 0.01f );
}
public static void foliage( Group group, int from, int to, Callback callback ) {
MagicMissile missile = ((MagicMissile)group.recycle( MagicMissile.class ));
missile.reset( from, to, callback );
missile.size( 10 );
missile.pour( LeafParticle.GENERAL, 0.03f );
}
public static void slowness( Group group, int from, int to, Callback callback ) {
MagicMissile missile = ((MagicMissile)group.recycle( MagicMissile.class ));
missile.reset( from, to, callback );
missile.pour( SlowParticle.FACTORY, 0.01f );
}
public static void force( Group group, int from, int to, Callback callback ) {
MagicMissile missile = ((MagicMissile)group.recycle( MagicMissile.class ));
missile.reset( from, to, callback );
missile.size( 0 );
missile.pour( ForceParticle.FACTORY, 0.01f );
}
public static void coldLight( Group group, int from, int to, Callback callback ) {
MagicMissile missile = ((MagicMissile)group.recycle( MagicMissile.class ));
missile.reset( from, to, callback );
missile.size( 4 );
missile.pour( ColdParticle.FACTORY, 0.01f );
}
public static void shadow( Group group, int from, int to, Callback callback ) {
MagicMissile missile = ((MagicMissile)group.recycle( MagicMissile.class ));
missile.reset( from, to, callback );
missile.size( 4 );
missile.pour( ShadowParticle.MISSILE, 0.01f );
}
public static void rainbow( Group group, int from, int to, Callback callback ) {
MagicMissile missile = ((MagicMissile)group.recycle( MagicMissile.class ));
missile.reset( from, to, callback );
missile.size( 4 );
missile.pour( RainbowParticle.BURST, 0.01f );
} }
@Override @Override

View File

@ -26,6 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.watabou.noosa.Game; import com.watabou.noosa.Game;
import com.watabou.noosa.Group; import com.watabou.noosa.Group;
import com.watabou.noosa.Image; import com.watabou.noosa.Image;
import com.watabou.noosa.Visual;
public class Surprise extends Image { public class Surprise extends Image {
@ -47,6 +48,14 @@ public class Surprise extends Image {
time = TIME_TO_FADE; time = TIME_TO_FADE;
} }
public void reset(Visual v) {
revive();
point(v.center(this));
time = TIME_TO_FADE;
}
@Override @Override
public void update() { public void update() {
super.update(); super.update();
@ -68,7 +77,7 @@ public class Surprise extends Image {
if (ch.sprite.parent != null) { if (ch.sprite.parent != null) {
Surprise s = (Surprise) ch.sprite.parent.recycle(Surprise.class); Surprise s = (Surprise) ch.sprite.parent.recycle(Surprise.class);
ch.sprite.parent.bringToFront(s); ch.sprite.parent.bringToFront(s);
s.reset(ch.pos); s.reset(ch.sprite);
s.angle = angle; s.angle = angle;
} }
} }
@ -79,9 +88,9 @@ public class Surprise extends Image {
public static void hit(int pos, float angle) { public static void hit(int pos, float angle) {
Group parent = Dungeon.hero.sprite.parent; Group parent = Dungeon.hero.sprite.parent;
Wound w = (Wound) parent.recycle(Wound.class); Surprise s = (Surprise) parent.recycle(Surprise.class);
parent.bringToFront(w); parent.bringToFront(s);
w.reset(pos); s.reset(pos);
w.angle = angle; s.angle = angle;
} }
} }

View File

@ -26,6 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.watabou.noosa.Game; import com.watabou.noosa.Game;
import com.watabou.noosa.Group; import com.watabou.noosa.Group;
import com.watabou.noosa.Image; import com.watabou.noosa.Image;
import com.watabou.noosa.Visual;
public class Wound extends Image { public class Wound extends Image {
@ -47,6 +48,14 @@ public class Wound extends Image {
time = TIME_TO_FADE; time = TIME_TO_FADE;
} }
public void reset(Visual v) {
revive();
point(v.center(this));
time = TIME_TO_FADE;
}
@Override @Override
public void update() { public void update() {
super.update(); super.update();
@ -68,7 +77,7 @@ public class Wound extends Image {
if (ch.sprite.parent != null) { if (ch.sprite.parent != null) {
Wound w = (Wound) ch.sprite.parent.recycle(Wound.class); Wound w = (Wound) ch.sprite.parent.recycle(Wound.class);
ch.sprite.parent.bringToFront(w); ch.sprite.parent.bringToFront(w);
w.reset(ch.pos); w.reset(ch.sprite);
w.angle = angle; w.angle = angle;
} }
} }

View File

@ -39,6 +39,7 @@ import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.sprites.MissileSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.MissileSprite;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton; import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.audio.Sample; import com.watabou.noosa.audio.Sample;
@ -500,14 +501,31 @@ public class Item implements Bundlable {
} }
final float finalDelay = delay; final float finalDelay = delay;
if (enemy != null) {
((MissileSprite) user.sprite.parent.recycle(MissileSprite.class)). ((MissileSprite) user.sprite.parent.recycle(MissileSprite.class)).
reset( user.pos, cell, this, new Callback() { reset(user.sprite,
enemy.sprite,
this,
new Callback() {
@Override @Override
public void call() { public void call() {
Item.this.detach(user.belongings.backpack).onThrow(cell); Item.this.detach(user.belongings.backpack).onThrow(cell);
user.spendAndNext(finalDelay); user.spendAndNext(finalDelay);
} }
}); });
} else {
((MissileSprite) user.sprite.parent.recycle(MissileSprite.class)).
reset(user.sprite,
dst,
this,
new Callback() {
@Override
public void call() {
Item.this.detach(user.belongings.backpack).onThrow(cell);
user.spendAndNext(finalDelay);
}
});
}
} }
protected static Hero curUser = null; protected static Hero curUser = null;

View File

@ -35,6 +35,7 @@ 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;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton; import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.utils.Callback; import com.watabou.utils.Callback;
@ -132,7 +133,7 @@ public class EtherealChains extends Artifact {
updateQuickslot(); updateQuickslot();
} }
curUser.busy(); curUser.busy();
curUser.sprite.parent.add(new Chains(curUser.pos, affected.pos, new Callback() { curUser.sprite.parent.add(new Chains(curUser.sprite.center(), affected.sprite.center(), new Callback() {
public void call() { public void call() {
Actor.add(new Pushing(affected, affected.pos, newMobPos, new Callback() { Actor.add(new Pushing(affected, affected.pos, newMobPos, new Callback() {
public void call() { public void call() {
@ -169,7 +170,7 @@ public class EtherealChains extends Artifact {
updateQuickslot(); updateQuickslot();
} }
curUser.busy(); curUser.busy();
curUser.sprite.parent.add(new Chains(curUser.pos, target, new Callback() { curUser.sprite.parent.add(new Chains(curUser.sprite.center(), DungeonTilemap.tileCenterToWorld(target), new Callback() {
public void call() { public void call() {
Actor.add(new Pushing(curUser, curUser.pos, newHeroPos, new Callback() { Actor.add(new Pushing(curUser, curUser.pos, newHeroPos, new Callback() {
public void call() { public void call() {

View File

@ -32,7 +32,6 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile; import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector; import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector;
@ -205,7 +204,11 @@ public class LloydsBeacon extends Artifact {
curUser.sprite.zap(bolt.collisionPos); curUser.sprite.zap(bolt.collisionPos);
curUser.busy(); curUser.busy();
MagicMissile.force(curUser.sprite.parent, bolt.sourcePos, bolt.collisionPos, new Callback() { MagicMissile.boltFromChar(curUser.sprite.parent,
MagicMissile.BEACON,
curUser.sprite,
bolt.collisionPos,
new Callback() {
@Override @Override
public void call() { public void call() {
if (ch != null) { if (ch != null) {
@ -219,7 +222,6 @@ public class LloydsBeacon extends Artifact {
} }
} while (pos == -1); } while (pos == -1);
if (pos == -1 || Dungeon.bossLevel()) { if (pos == -1 || Dungeon.bossLevel()) {
GLog.w( Messages.get(ScrollOfTeleportation.class, "no_tele") ); GLog.w( Messages.get(ScrollOfTeleportation.class, "no_tele") );

View File

@ -300,16 +300,20 @@ public class Potion extends Item {
} }
protected void splash( int cell ) { protected void splash( int cell ) {
final int color = ItemSprite.pick( image, 8, 10 );
Splash.at( cell, color, 5 );
Fire fire = (Fire)Dungeon.level.blobs.get( Fire.class ); Fire fire = (Fire)Dungeon.level.blobs.get( Fire.class );
if (fire != null) if (fire != null)
fire.clear( cell ); fire.clear( cell );
final int color = ItemSprite.pick( image, 8, 10 );
Char ch = Actor.findChar(cell); Char ch = Actor.findChar(cell);
if (ch != null) if (ch != null) {
Buff.detach(ch, Burning.class); Buff.detach(ch, Burning.class);
Splash.at( ch.sprite.center(), color, 5 );
} else {
Splash.at( cell, color, 5 );
}
} }
@Override @Override

View File

@ -53,7 +53,6 @@ import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TimekeepersHourg
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRecharging; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRecharging;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.CursingTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.CursingTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.LightningTrap; import com.shatteredpixel.shatteredpixeldungeon.levels.traps.LightningTrap;
@ -443,7 +442,11 @@ public class CursedWand {
} }
private static void cursedFX(final Hero user, final Ballistica bolt, final Callback callback){ private static void cursedFX(final Hero user, final Ballistica bolt, final Callback callback){
MagicMissile.rainbow(user.sprite.parent, bolt.sourcePos, bolt.collisionPos, callback); MagicMissile.boltFromChar( user.sprite.parent,
MagicMissile.RAINBOW,
user.sprite,
bolt.collisionPos,
callback);
Sample.INSTANCE.play( Assets.SND_ZAP ); Sample.INSTANCE.play( Assets.SND_ZAP );
} }

View File

@ -234,7 +234,11 @@ public abstract class Wand extends Item {
} }
protected void fx( Ballistica bolt, Callback callback ) { protected void fx( Ballistica bolt, Callback callback ) {
MagicMissile.whiteLight( curUser.sprite.parent, bolt.sourcePos, bolt.collisionPos, callback ); MagicMissile.boltFromChar( curUser.sprite.parent,
MagicMissile.MAGIC_MISSILE,
curUser.sprite,
bolt.collisionPos,
callback);
Sample.INSTANCE.play( Assets.SND_ZAP ); Sample.INSTANCE.play( Assets.SND_ZAP );
} }

View File

@ -159,7 +159,11 @@ public class WandOfBlastWave extends DamageWand {
@Override @Override
protected void fx(Ballistica bolt, Callback callback) { protected void fx(Ballistica bolt, Callback callback) {
MagicMissile.slowness(curUser.sprite.parent, bolt.sourcePos, bolt.collisionPos, callback); MagicMissile.boltFromChar( curUser.sprite.parent,
MagicMissile.FORCE,
curUser.sprite,
bolt.collisionPos,
callback);
Sample.INSTANCE.play(Assets.SND_ZAP); Sample.INSTANCE.play(Assets.SND_ZAP);
} }

View File

@ -103,7 +103,11 @@ public class WandOfCorruption extends Wand {
@Override @Override
protected void fx(Ballistica bolt, Callback callback) { protected void fx(Ballistica bolt, Callback callback) {
MagicMissile.shadow(curUser.sprite.parent, bolt.sourcePos, bolt.collisionPos, callback); MagicMissile.boltFromChar( curUser.sprite.parent,
MagicMissile.SHADOW,
curUser.sprite,
bolt.collisionPos,
callback);
Sample.INSTANCE.play( Assets.SND_ZAP ); Sample.INSTANCE.play( Assets.SND_ZAP );
} }

View File

@ -159,9 +159,18 @@ public class WandOfFireblast extends DamageWand {
for (int cell : visualCells){ for (int cell : visualCells){
//this way we only get the cells at the tip, much better performance. //this way we only get the cells at the tip, much better performance.
MagicMissile.fire(curUser.sprite.parent, bolt.sourcePos, cell, null); ((MagicMissile)curUser.sprite.parent.recycle( MagicMissile.class )).reset(
MagicMissile.FIRE_CONE,
curUser.sprite,
cell,
null
);
} }
MagicMissile.fire( curUser.sprite.parent, bolt.sourcePos, bolt.path.get(dist), callback ); MagicMissile.boltFromChar( curUser.sprite.parent,
MagicMissile.FIRE_CONE,
curUser.sprite,
bolt.path.get(dist/2),
callback );
Sample.INSTANCE.play( Assets.SND_ZAP ); Sample.INSTANCE.play( Assets.SND_ZAP );
} }

View File

@ -91,7 +91,11 @@ public class WandOfFrost extends DamageWand {
@Override @Override
protected void fx(Ballistica bolt, Callback callback) { protected void fx(Ballistica bolt, Callback callback) {
MagicMissile.blueLight(curUser.sprite.parent, bolt.sourcePos, bolt.collisionPos, callback); MagicMissile.boltFromChar(curUser.sprite.parent,
MagicMissile.FROST,
curUser.sprite,
bolt.collisionPos,
callback);
Sample.INSTANCE.play(Assets.SND_ZAP); Sample.INSTANCE.play(Assets.SND_ZAP);
} }

View File

@ -110,7 +110,7 @@ public class WandOfLightning extends DamageWand {
//the hero is only zapped if they are adjacent //the hero is only zapped if they are adjacent
continue; continue;
else if (n != null && !affected.contains( n )) { else if (n != null && !affected.contains( n )) {
arcs.add(new Lightning.Arc(ch.pos, n.pos)); arcs.add(new Lightning.Arc(ch.sprite.center(), n.sprite.center()));
arc(n); arc(n);
} }
} }
@ -122,19 +122,20 @@ public class WandOfLightning extends DamageWand {
affected.clear(); affected.clear();
arcs.clear(); arcs.clear();
arcs.add( new Lightning.Arc(bolt.sourcePos, bolt.collisionPos));
int cell = bolt.collisionPos; int cell = bolt.collisionPos;
Char ch = Actor.findChar( cell ); Char ch = Actor.findChar( cell );
if (ch != null) { if (ch != null) {
arcs.add( new Lightning.Arc(curUser.sprite.center(), ch.sprite.center()));
arc(ch); arc(ch);
} else { } else {
arcs.add( new Lightning.Arc(curUser.sprite.center(), bolt.collisionPos));
CellEmitter.center( cell ).burst( SparkParticle.FACTORY, 3 ); CellEmitter.center( cell ).burst( SparkParticle.FACTORY, 3 );
} }
//don't want to wait for the effect before processing damage. //don't want to wait for the effect before processing damage.
curUser.sprite.parent.add( new Lightning( arcs, null ) ); curUser.sprite.parent.addToFront( new Lightning( arcs, null ) );
callback.call(); callback.call();
} }

View File

@ -213,9 +213,18 @@ public class WandOfRegrowth extends Wand {
for (int cell : visualCells){ for (int cell : visualCells){
//this way we only get the cells at the tip, much better performance. //this way we only get the cells at the tip, much better performance.
MagicMissile.foliage(curUser.sprite.parent, bolt.sourcePos, cell, null); ((MagicMissile)curUser.sprite.parent.recycle( MagicMissile.class )).reset(
MagicMissile.FOLIAGE_CONE,
curUser.sprite,
cell,
null
);
} }
MagicMissile.foliage( curUser.sprite.parent, bolt.sourcePos, bolt.path.get(dist), callback ); MagicMissile.boltFromChar( curUser.sprite.parent,
MagicMissile.FOLIAGE_CONE,
curUser.sprite,
bolt.path.get(dist/2),
callback );
Sample.INSTANCE.play( Assets.SND_ZAP ); Sample.INSTANCE.play( Assets.SND_ZAP );
} }

View File

@ -28,7 +28,6 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.VenomGas;
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile; import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Venomous; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Venomous;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
@ -61,7 +60,12 @@ public class WandOfVenom extends Wand {
@Override @Override
protected void fx(Ballistica bolt, Callback callback) { protected void fx(Ballistica bolt, Callback callback) {
MagicMissile.poison(curUser.sprite.parent, bolt.sourcePos, bolt.collisionPos, callback); MagicMissile.boltFromChar(
curUser.sprite.parent,
MagicMissile.POISON,
curUser.sprite,
bolt.collisionPos,
callback);
Sample.INSTANCE.play(Assets.SND_ZAP); Sample.INSTANCE.play(Assets.SND_ZAP);
} }

View File

@ -51,10 +51,10 @@ public class Shocking extends Weapon.Enchantment {
affected.add(attacker); affected.add(attacker);
arcs.clear(); arcs.clear();
arcs.add(new Lightning.Arc(attacker.pos, defender.pos)); arcs.add(new Lightning.Arc(attacker.sprite.center(), defender.sprite.center()));
hit(defender, Random.Int(1, damage / 3)); hit(defender, Random.Int(1, damage / 3));
attacker.sprite.parent.add( new Lightning( arcs, null ) ); attacker.sprite.parent.addToFront( new Lightning( arcs, null ) );
} }
@ -83,11 +83,10 @@ public class Shocking extends Weapon.Enchantment {
ch.sprite.centerEmitter().burst(SparkParticle.FACTORY, 3); ch.sprite.centerEmitter().burst(SparkParticle.FACTORY, 3);
ch.sprite.flash(); ch.sprite.flash();
HashSet<Char> ns = new HashSet<Char>();
for (int i = 0; i < PathFinder.NEIGHBOURS8.length; i++) { for (int i = 0; i < PathFinder.NEIGHBOURS8.length; i++) {
Char n = Actor.findChar( ch.pos + PathFinder.NEIGHBOURS8[i] ); Char n = Actor.findChar( ch.pos + PathFinder.NEIGHBOURS8[i] );
if (n != null && !affected.contains( n )) { if (n != null && !affected.contains( n )) {
arcs.add(new Lightning.Arc(ch.pos, n.pos)); arcs.add(new Lightning.Arc(ch.sprite.center(), n.sprite.center()));
hit(n, Random.Int(damage / 2, damage)); hit(n, Random.Int(damage / 2, damage));
} }
} }

View File

@ -29,6 +29,7 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.audio.Sample; import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Callback; import com.watabou.utils.Callback;
@ -64,7 +65,11 @@ public class GrimTrap extends Trap {
if (target != null){ if (target != null){
final Char finalTarget = target; final Char finalTarget = target;
final GrimTrap trap = this; final GrimTrap trap = this;
MagicMissile.shadow(target.sprite.parent, pos, target.pos, new Callback() { ((MagicMissile)target.sprite.parent.recycle(MagicMissile.class)).reset(
MagicMissile.SHADOW,
DungeonTilemap.tileCenterToWorld(pos),
target.sprite.center(),
new Callback() {
@Override @Override
public void call() { public void call() {
if (!finalTarget.isAlive()) return; if (!finalTarget.isAlive()) return;

View File

@ -63,7 +63,10 @@ public class BurningFistSprite extends MobSprite {
if (anim == attack) { if (anim == attack) {
Sample.INSTANCE.play( Assets.SND_ZAP ); Sample.INSTANCE.play( Assets.SND_ZAP );
MagicMissile.shadow( parent, ch.pos, posToShoot, MagicMissile.boltFromChar( parent,
MagicMissile.SHADOW,
this,
posToShoot,
new Callback() { new Callback() {
@Override @Override
public void call() { public void call() {

View File

@ -139,14 +139,9 @@ public class CharSprite extends MovieClip implements Tweener.Listener, MovieClip
if (args.length > 0) { if (args.length > 0) {
text = Messages.format( text, args ); text = Messages.format( text, args );
} }
if (ch != null) {
PointF tile = DungeonTilemap.tileCenterToWorld(ch.pos);
FloatingText.show( tile.x, tile.y-(width*0.5f), ch.pos, text, color );
} else {
FloatingText.show( x + width * 0.5f, y, text, color ); FloatingText.show( x + width * 0.5f, y, text, color );
} }
} }
}
public void idle() { public void idle() {
play( idle ); play( idle );

View File

@ -22,6 +22,7 @@ package com.shatteredpixel.shatteredpixeldungeon.sprites;
import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap; import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Eye; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Eye;
@ -104,8 +105,12 @@ public class EyeSprite extends MobSprite {
if (anim == zap) { if (anim == zap) {
if (Dungeon.visible[ch.pos] || Dungeon.visible[zapPos]) { if (Dungeon.visible[ch.pos] || Dungeon.visible[zapPos]) {
if (Actor.findChar(zapPos) != null){
parent.add(new Beam.DeathRay(center(), Actor.findChar(zapPos).sprite.center()));
} else {
parent.add(new Beam.DeathRay(center(), DungeonTilemap.tileCenterToWorld(zapPos))); parent.add(new Beam.DeathRay(center(), DungeonTilemap.tileCenterToWorld(zapPos)));
} }
}
((Eye)ch).deathGaze(); ((Eye)ch).deathGaze();
ch.next(); ch.next();
} else if (anim == die){ } else if (anim == die){

View File

@ -22,6 +22,7 @@ package com.shatteredpixel.shatteredpixeldungeon.sprites;
import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap; import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap;
import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.watabou.noosa.Visual;
import com.watabou.noosa.tweeners.PosTweener; import com.watabou.noosa.tweeners.PosTweener;
import com.watabou.noosa.tweeners.Tweener; import com.watabou.noosa.tweeners.Tweener;
import com.watabou.utils.Callback; import com.watabou.utils.Callback;
@ -39,24 +40,42 @@ public class MissileSprite extends ItemSprite implements Tweener.Listener {
} }
public void reset( int from, int to, Item item, Callback listener ) { public void reset( int from, int to, Item item, Callback listener ) {
if (item == null) { reset( DungeonTilemap.tileToWorld( from ),
reset( from, to, 0, null, listener ); DungeonTilemap.tileToWorld( to ),
} else { item,
reset( from, to, item.image(), item.glowing(), listener ); listener);
}
} }
public void reset( int from, int to, int image, Glowing glowing, Callback listener ) { public void reset( Visual from, Visual to, Item item, Callback listener ) {
reset( from.center(this),
to.center(this),
item,
listener);
}
public void reset( Visual from, int to, Item item, Callback listener ) {
reset( from.center(this),
DungeonTilemap.tileToWorld( to ),
item,
listener);
}
public void reset( PointF from, PointF to, Item item, Callback listener) {
revive(); revive();
view( image, glowing ); int image;
if (item == null){
view( image = 0, null);;
} else {
//no particle effects
view( image = item.image(), item.glowing() );
}
this.callback = listener; this.callback = listener;
point( DungeonTilemap.tileToWorld( from ) ); point( from );
PointF dest = DungeonTilemap.tileToWorld( to );
PointF d = PointF.diff( dest, point() ); PointF d = PointF.diff( to, from );
speed.set( d ).normalize().scale( SPEED ); speed.set( d ).normalize().scale( SPEED );
if (image == ItemSpriteSheet.DART || image == ItemSpriteSheet.INCENDIARY_DART if (image == ItemSpriteSheet.DART || image == ItemSpriteSheet.INCENDIARY_DART
@ -71,7 +90,7 @@ public class MissileSprite extends ItemSprite implements Tweener.Listener {
} }
PosTweener tweener = new PosTweener( this, dest, d.length() / SPEED ); PosTweener tweener = new PosTweener( this, to, d.length() / SPEED );
tweener.listener = this; tweener.listener = this;
parent.add( tweener ); parent.add( tweener );
} }

View File

@ -58,7 +58,10 @@ public class WarlockSprite extends MobSprite {
turnTo( ch.pos , cell ); turnTo( ch.pos , cell );
play( zap ); play( zap );
MagicMissile.shadow( parent, ch.pos, cell, MagicMissile.boltFromChar( parent,
MagicMissile.SHADOW,
this,
cell,
new Callback() { new Callback() {
@Override @Override
public void call() { public void call() {

View File

@ -179,12 +179,9 @@ public class QuickSlotButton extends Button implements WndBag.Listener {
CharSprite sprite = lastTarget.sprite; CharSprite sprite = lastTarget.sprite;
sprite.parent.addToFront( crossM ); sprite.parent.addToFront( crossM );
crossM.point(sprite.center(crossM));
crossM.x = sprite.x + ( sprite.width() - crossM.width())/2f; crossB.point(slot.icon.center(crossB));
crossM.y = sprite.y + ( sprite.height() - crossM.height())/2f;
crossB.x = x + (width - crossB.width) / 2;
crossB.y = y + (height - crossB.height) / 2;
crossB.visible = true; crossB.visible = true;
} else { } else {