diff --git a/core/src/main/assets/sprites/crystal_spire.png b/core/src/main/assets/sprites/crystal_spire.png index fc1927ea3..d2eb6069d 100644 Binary files a/core/src/main/assets/sprites/crystal_spire.png and b/core/src/main/assets/sprites/crystal_spire.png differ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalGuardian.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalGuardian.java index 082e89a45..1b78362a9 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalGuardian.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalGuardian.java @@ -40,6 +40,11 @@ public class CrystalGuardian extends Mob{ state = SLEEPING; } + @Override + public boolean reset() { + return true; + } + public CrystalGuardian(){ super(); switch (Random.Int(3)){ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalSpire.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalSpire.java index 683c01a5f..594b29f52 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalSpire.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/CrystalSpire.java @@ -21,17 +21,103 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.mobs; +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Amok; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Dread; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Sleep; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith; +import com.shatteredpixel.shatteredpixeldungeon.items.quest.Pickaxe; +import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.CrystalSpireSprite; +import com.watabou.noosa.audio.Sample; import com.watabou.utils.Bundle; +import com.watabou.utils.Callback; import com.watabou.utils.Random; public class CrystalSpire extends Mob { { - HP = HT = 1; + HP = HT = 200; spriteClass = CrystalSpireSprite.class; state = PASSIVE; + + alignment = Alignment.NEUTRAL; + + properties.add(Property.IMMOVABLE); + properties.add(Property.MINIBOSS); + properties.add(Property.INORGANIC); + } + + @Override + protected boolean act() { + alerted = false; + return super.act(); + } + + //TODO just whaling on this thing is boring, it has to do something in retaliation other than aggroing guardians + + @Override + public void beckon(int cell) { + //do nothing + } + + @Override + public boolean reset() { + return true; + } + + @Override + public void damage(int dmg, Object src) { + if (!(src instanceof Pickaxe) ){ + dmg = 0; + } + super.damage(dmg, src); + } + + @Override + public boolean interact(Char c) { + if (c == Dungeon.hero){ + final Pickaxe p = Dungeon.hero.belongings.getItem(Pickaxe.class); + + if (p == null){ + //maybe a game log entry here? + return true; + } + + Dungeon.hero.sprite.attack(pos, new Callback() { + @Override + public void call() { + //does its own special damage calculation that's only influenced by pickaxe level + int dmg = Random.NormalIntRange(3+p.buffedLvl(), 15+3*p.buffedLvl()); + + damage(dmg, p); + sprite.bloodBurstA(Dungeon.hero.sprite.center(), dmg); + sprite.flash(); + + if (isAlive()) { + Sample.INSTANCE.play(Assets.Sounds.SHATTER, 1f, Random.Float(1.15f, 1.25f)); + ((CrystalSpireSprite) sprite).updateIdle(); + } else { + Sample.INSTANCE.play(Assets.Sounds.SHATTER); + Sample.INSTANCE.playDelayed(Assets.Sounds.ROCKS, 0.1f); + PixelScene.shake( 3, 0.7f ); + Blacksmith.Quest.beatBoss(); + } + + Dungeon.hero.spendAndNext(Actor.TICK); + } + }); + return false; + + } + return true; } public CrystalSpire(){ @@ -68,4 +154,13 @@ public class CrystalSpire extends Mob { spriteClass = bundle.getClass(SPRITE); } + { + immunities.add( Paralysis.class ); + immunities.add( Amok.class ); + immunities.add( Sleep.class ); + immunities.add( Terror.class ); + immunities.add( Dread.class ); + immunities.add( Vertigo.class ); + } + } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java index d864f5123..d992dfea1 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/Blacksmith.java @@ -405,6 +405,10 @@ public class Blacksmith extends NPC { started = true; } + public static boolean beatBoss(){ + return bossBeaten = true; + } + public static boolean bossBeaten(){ return bossBeaten; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/Splash.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/Splash.java index 39d4c7a35..1753faad9 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/Splash.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/Splash.java @@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.effects; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap; +import com.watabou.noosa.Visual; import com.watabou.noosa.particles.Emitter; import com.watabou.noosa.particles.PixelParticle; import com.watabou.utils.PointF; @@ -66,6 +67,21 @@ public class Splash { emitter.burst( FACTORY, n ); } + public static void around(Visual v, final int color, int n ) { + if (n <= 0) { + return; + } + + Emitter emitter = GameScene.emitter(); + if (emitter == null) return; + emitter.pos( v ); + + FACTORY.color = color; + FACTORY.dir = -3.1415926f / 2; + FACTORY.cone = 3.1415926f; + emitter.burst( FACTORY, n ); + } + public static void at( PointF p, final float dir, final float cone, final int color, int n, float interval ) { if (n <= 0) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CrystalSpireSprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CrystalSpireSprite.java index e05ebd33f..d3e14e270 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CrystalSpireSprite.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/CrystalSpireSprite.java @@ -23,12 +23,17 @@ package com.shatteredpixel.shatteredpixeldungeon.sprites; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.effects.Splash; import com.watabou.noosa.TextureFilm; public abstract class CrystalSpireSprite extends MobSprite { { perspectiveRaise = 7 / 16f; //7 pixels + + shadowWidth = 1f; + shadowHeight = 1f; + shadowOffset = 1f; } public CrystalSpireSprite(){ @@ -46,15 +51,44 @@ public abstract class CrystalSpireSprite extends MobSprite { zap = idle.clone(); die = new Animation(1, false); - die.frames( frames, 0+c ); + die.frames( frames, 4+c ); play(idle); } + public void updateIdle(){ + float hpPercent = 1f; + if (ch != null){ + hpPercent = ch.HP/(float)ch.HT; + } + + TextureFilm frames = new TextureFilm( texture, 30, 45 ); + + if (hpPercent > 0.8f){ + idle.frames( frames, 0+texOffset() ); + } else if (hpPercent > 0.5f){ + idle.frames( frames, 1+texOffset() ); + } else if (hpPercent > 0.25f){ + idle.frames( frames, 2+texOffset() ); + } else { + idle.frames( frames, 3+texOffset() ); + } + play(idle, true); + run = idle.clone(); + attack = idle.clone(); + zap = idle.clone(); + } + @Override public void link(Char ch) { super.link(ch); - renderShadow = false; + updateIdle(); + } + + @Override + public void die() { + super.die(); + Splash.around(this, blood(), 100); } protected abstract int texOffset(); @@ -73,7 +107,7 @@ public abstract class CrystalSpireSprite extends MobSprite { public static class Green extends CrystalSpireSprite { @Override protected int texOffset() { - return 1; + return 5; } @Override public int blood() { @@ -84,7 +118,7 @@ public abstract class CrystalSpireSprite extends MobSprite { public static class Red extends CrystalSpireSprite { @Override protected int texOffset() { - return 2; + return 10; } @Override public int blood() { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/SpawnerSprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/SpawnerSprite.java index 068cb9ac6..0ee22b7a0 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/SpawnerSprite.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/SpawnerSprite.java @@ -73,7 +73,7 @@ public class SpawnerSprite extends MobSprite { @Override public void die() { - Splash.at( center(), blood(), 100 ); + Splash.around( this, blood(), 100 ); killAndErase(); }