diff --git a/core/src/main/assets/elemental.png b/core/src/main/assets/elemental.png index e7cc6c89c..5d2487d00 100644 Binary files a/core/src/main/assets/elemental.png and b/core/src/main/assets/elemental.png differ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java index 1c13560f6..802820c25 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java @@ -118,6 +118,12 @@ public class ShatteredPixelDungeon extends Game { com.watabou.utils.Bundle.addAlias( com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM100.class, "com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Shaman"); + com.watabou.utils.Bundle.addAlias( + com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Elemental.Fire.class, + "com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Elemental"); + com.watabou.utils.Bundle.addAlias( + com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Elemental.NewbornFire.class, + "com.shatteredpixel.shatteredpixeldungeon.actors.mobs.NewbornElemental"); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java index 1f79eec04..d4d5890de 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java @@ -60,6 +60,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Weakness; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Elemental; import com.shatteredpixel.shatteredpixeldungeon.items.BrokenSeal; import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.AntiMagic; import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Brimstone; @@ -69,6 +70,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRetributio import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfPsionicBlast; import com.shatteredpixel.shatteredpixeldungeon.items.stones.StoneOfAggression; import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfFireblast; +import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfFrost; import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfLightning; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Blazing; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Grim; @@ -669,11 +671,13 @@ public abstract class Char extends Actor { new HashSet( Arrays.asList(Bleeding.class, ToxicGas.class, Poison.class) )), BLOB_IMMUNE ( new HashSet(), new HashSet( Arrays.asList(Blob.class) )), - FIERY ( new HashSet( Arrays.asList(WandOfFireblast.class)), + FIERY ( new HashSet( Arrays.asList(WandOfFireblast.class, Elemental.Fire.class)), new HashSet( Arrays.asList(Burning.class, Blazing.class))), + ICY ( new HashSet( Arrays.asList(WandOfFrost.class, Elemental.Frost.class)), + new HashSet( Arrays.asList(Frost.class, Chill.class))), ACIDIC ( new HashSet( Arrays.asList(Corrosion.class)), new HashSet( Arrays.asList(Ooze.class))), - ELECTRIC ( new HashSet( Arrays.asList(WandOfLightning.class, Shocking.class, Potential.class, Electricity.class, ShockingDart.class)), + ELECTRIC ( new HashSet( Arrays.asList(WandOfLightning.class, Shocking.class, Potential.class, Electricity.class, ShockingDart.class, Elemental.Shock.class )), new HashSet()), IMMOVABLE; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bestiary.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bestiary.java index 468e12e4b..89c06f038 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bestiary.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Bestiary.java @@ -123,26 +123,26 @@ public class Bestiary { case 16: //5x elemental, 5x warlock, 1x monk return new ArrayList<>(Arrays.asList( - Elemental.class, Elemental.class, Elemental.class, Elemental.class, Elemental.class, + Elemental.random(), Elemental.random(), Elemental.random(), Elemental.random(), Elemental.random(), Warlock.class, Warlock.class, Warlock.class, Warlock.class, Warlock.class, Monk.class)); case 17: //2x elemental, 2x warlock, 2x monk return new ArrayList<>(Arrays.asList( - Elemental.class, Elemental.class, + Elemental.random(), Elemental.random(), Warlock.class, Warlock.class, Monk.class, Monk.class)); case 18: //1x elemental, 1x warlock, 2x monk, 1x golem return new ArrayList<>(Arrays.asList( - Elemental.class, + Elemental.random(), Warlock.class, Monk.class, Monk.class, Golem.class)); case 19: case 20: //1x elemental, 1x warlock, 2x monk, 3x golem return new ArrayList<>(Arrays.asList( - Elemental.class, + Elemental.random(), Warlock.class, Monk.class, Monk.class, Golem.class, Golem.class, Golem.class)); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Elemental.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Elemental.java index 82aed83e3..0b20e46ae 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Elemental.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Elemental.java @@ -21,33 +21,44 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.mobs; +import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Freezing; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Blindness; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Chill; -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Frost; +import com.shatteredpixel.shatteredpixeldungeon.effects.Lightning; +import com.shatteredpixel.shatteredpixeldungeon.effects.Splash; +import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfFrost; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLiquidFlame; +import com.shatteredpixel.shatteredpixeldungeon.items.quest.Embers; +import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRecharging; +import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTransmutation; +import com.shatteredpixel.shatteredpixeldungeon.items.wands.CursedWand; +import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Shocking; +import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; +import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.ElementalSprite; +import com.watabou.noosa.audio.Sample; +import com.watabou.utils.Bundle; +import com.watabou.utils.Callback; import com.watabou.utils.Random; -public class Elemental extends Mob { +import java.util.ArrayList; + +public abstract class Elemental extends Mob { { - spriteClass = ElementalSprite.class; - - HP = HT = 65; + HP = HT = 60; defenseSkill = 20; EXP = 10; maxLvl = 20; flying = true; - - loot = new PotionOfLiquidFlame(); - lootChance = 0.1f; - - properties.add(Property.FIERY); } @Override @@ -65,26 +76,258 @@ public class Elemental extends Mob { return Random.NormalIntRange(0, 5); } + private int rangedCooldown = Random.NormalIntRange( 3, 5 ); + + @Override + protected boolean act() { + if (state == HUNTING){ + rangedCooldown--; + } + + return super.act(); + } + + @Override + protected boolean canAttack( Char enemy ) { + if (rangedCooldown <= 0) { + return new Ballistica( pos, enemy.pos, Ballistica.MAGIC_BOLT ).collisionPos == enemy.pos; + } else { + return super.canAttack( enemy ); + } + } + + protected boolean doAttack( Char enemy ) { + + if (Dungeon.level.adjacent( pos, enemy.pos )) { + + return super.doAttack( enemy ); + + } else { + + if (sprite != null && (sprite.visible || enemy.sprite.visible)) { + sprite.zap( enemy.pos ); + return false; + } else { + zap(); + return true; + } + } + } + @Override public int attackProc( Char enemy, int damage ) { damage = super.attackProc( enemy, damage ); - if (Random.Int( 2 ) == 0) { - Buff.affect( enemy, Burning.class ).reignite( enemy ); - } + meleeProc( enemy, damage ); return damage; } + private void zap() { + spend( 1f ); + + if (hit( this, enemy, true )) { + + rangedProc( enemy ); + rangedCooldown = Random.NormalIntRange( 3, 5 ); + + } else { + enemy.sprite.showStatus( CharSprite.NEUTRAL, enemy.defenseVerb() ); + } + } + + public void onZapComplete() { + zap(); + next(); + } + @Override public void add( Buff buff ) { - if (buff instanceof Frost || buff instanceof Chill) { - if (Dungeon.level.water[this.pos]) - damage( Random.NormalIntRange( HT / 2, HT ), buff ); - else - damage( Random.NormalIntRange( 1, HT * 2 / 3 ), buff ); + if (harmfulBuffs.contains( buff.getClass() )) { + damage( Random.NormalIntRange( HT/2, HT * 3/5 ), buff ); } else { super.add( buff ); } } + protected abstract void meleeProc( Char enemy, int damage ); + protected abstract void rangedProc( Char enemy ); + + protected ArrayList> harmfulBuffs = new ArrayList<>(); + + private static final String COOLDOWN = "cooldown"; + + @Override + public void storeInBundle( Bundle bundle ) { + super.storeInBundle( bundle ); + bundle.put( COOLDOWN, rangedCooldown ); + } + + @Override + public void restoreFromBundle( Bundle bundle ) { + super.restoreFromBundle( bundle ); + if (bundle.contains( COOLDOWN )){ + rangedCooldown = bundle.getInt( COOLDOWN ); + } + } + + public static class Fire extends Elemental { + + { + spriteClass = ElementalSprite.Fire.class; + + loot = new PotionOfLiquidFlame(); + lootChance = 1/8f; + + properties.add( Property.FIERY ); + + harmfulBuffs.add( com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Frost.class ); + harmfulBuffs.add( Chill.class ); + } + + @Override + protected void meleeProc( Char enemy, int damage ) { + if (Random.Int( 2 ) == 0 && !Dungeon.level.water[enemy.pos]) { + Buff.affect( enemy, Burning.class ).reignite( enemy ); + Splash.at( enemy.sprite.center(), sprite.blood(), 5); + } + } + + @Override + protected void rangedProc( Char enemy ) { + if (!Dungeon.level.water[enemy.pos]) { + Buff.affect( enemy, Burning.class ).reignite( enemy, 4f ); + } + Splash.at( enemy.sprite.center(), sprite.blood(), 5); + } + } + + //used in wandmaker quest + public static class NewbornFire extends Fire { + + { + spriteClass = ElementalSprite.NewbornFire.class; + + HT = 60; + HP = HT/2; //32 + + defenseSkill = 12; + + EXP = 7; + + loot = new Embers(); + lootChance = 1f; + + properties.add(Property.MINIBOSS); + } + + } + + public static class Frost extends Elemental { + + { + spriteClass = ElementalSprite.Frost.class; + + loot = new PotionOfFrost(); + lootChance = 1/8f; + + properties.add( Property.ICY ); + + harmfulBuffs.add( Burning.class ); + } + + @Override + protected void meleeProc( Char enemy, int damage ) { + if (Random.Int( 3 ) == 0 || Dungeon.level.water[enemy.pos]) { + Freezing.freeze( enemy.pos ); + Splash.at( enemy.sprite.center(), sprite.blood(), 5); + } + } + + @Override + protected void rangedProc( Char enemy ) { + Freezing.freeze( enemy.pos ); + Splash.at( enemy.sprite.center(), sprite.blood(), 5); + } + } + + public static class Shock extends Elemental { + + { + spriteClass = ElementalSprite.Shock.class; + + loot = new ScrollOfRecharging(); + lootChance = 1/4f; + + properties.add( Property.ELECTRIC ); + } + + @Override + protected void meleeProc( Char enemy, int damage ) { + ArrayList affected = new ArrayList<>(); + ArrayList arcs = new ArrayList<>(); + Shocking.arc( this, enemy, 2, affected, arcs ); + + if (!Dungeon.level.water[enemy.pos]) { + affected.remove( enemy ); + } + + for (Char ch : affected) { + ch.damage( Math.round( damage * 0.4f ), this ); + } + + sprite.parent.addToFront( new Lightning( arcs, null ) ); + Sample.INSTANCE.play( Assets.SND_LIGHTNING ); + } + + @Override + protected void rangedProc( Char enemy ) { + Buff.affect( enemy, Blindness.class, 5f ); + GameScene.flash( 0xFFFFFF ); + } + } + + public static class Chaos extends Elemental { + + { + spriteClass = ElementalSprite.Chaos.class; + + loot = new ScrollOfTransmutation(); + lootChance = 1f; + } + + @Override + protected void meleeProc( Char enemy, int damage ) { + CursedWand.cursedZap( null, this, new Ballistica( pos, enemy.pos, Ballistica.MAGIC_BOLT ), new Callback() { + @Override + public void call() { + next(); + } + } ); + } + + @Override + protected void rangedProc( Char enemy ) { + CursedWand.cursedZap( null, this, new Ballistica( pos, enemy.pos, Ballistica.MAGIC_BOLT ), new Callback() { + @Override + public void call() { + next(); + } + } ); + } + } + + public static Class random(){ + if (Random.Int( 50 ) == 0){ + return Chaos.class; + } + + float roll = Random.Float(); + if (roll < 0.4f){ + return Fire.class; + } else if (roll < 0.8f){ + return Frost.class; + } else { + return Shock.class; + } + } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/NewbornElemental.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/NewbornElemental.java deleted file mode 100644 index 4809bcdd3..000000000 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/NewbornElemental.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Pixel Dungeon - * Copyright (C) 2012-2015 Oleg Dolya - * - * Shattered Pixel Dungeon - * Copyright (C) 2014-2019 Evan Debenham - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see - */ - -package com.shatteredpixel.shatteredpixeldungeon.actors.mobs; - -import com.shatteredpixel.shatteredpixeldungeon.Dungeon; -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Chill; -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Frost; -import com.shatteredpixel.shatteredpixeldungeon.items.quest.Embers; -import com.shatteredpixel.shatteredpixeldungeon.sprites.NewbornElementalSprite; - -public class NewbornElemental extends Elemental { - - { - spriteClass = NewbornElementalSprite.class; - - HT = 65; - HP = HT/2; //32 - - defenseSkill = 12; - - EXP = 7; - - properties.add(Property.MINIBOSS); - } - - @Override - public void add(Buff buff) { - if (buff instanceof Frost || buff instanceof Chill) { - die(buff); - } else { - super.add(buff); - } - } - - @Override - public void die(Object cause) { - super.die(cause); - Dungeon.level.drop( new Embers(), pos ).sprite.drop(); - } -} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/CeremonialCandle.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/CeremonialCandle.java index 1810dea9b..4ff01833e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/CeremonialCandle.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/quest/CeremonialCandle.java @@ -26,7 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; -import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.NewbornElemental; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Elemental; import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle; import com.shatteredpixel.shatteredpixeldungeon.items.Heap; @@ -96,8 +96,8 @@ public class CeremonialCandle extends Item { heapRight.pickUp(); heapBottom.pickUp(); heapLeft.pickUp(); - - NewbornElemental elemental = new NewbornElemental(); + + Elemental.NewbornFire elemental = new Elemental.NewbornFire(); Char ch = Actor.findChar( ritualPos ); if (ch != null) { ArrayList candidates = new ArrayList<>(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ElementalSprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ElementalSprite.java index 410778bfa..386530b89 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ElementalSprite.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ElementalSprite.java @@ -23,28 +23,50 @@ package com.shatteredpixel.shatteredpixeldungeon.sprites; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Elemental; +import com.shatteredpixel.shatteredpixeldungeon.effects.Beam; +import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile; +import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle; +import com.shatteredpixel.shatteredpixeldungeon.effects.particles.FlameParticle; +import com.shatteredpixel.shatteredpixeldungeon.effects.particles.RainbowParticle; +import com.shatteredpixel.shatteredpixeldungeon.effects.particles.SparkParticle; +import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap; import com.watabou.noosa.TextureFilm; +import com.watabou.noosa.audio.Sample; +import com.watabou.noosa.particles.Emitter; +import com.watabou.utils.Callback; -public class ElementalSprite extends MobSprite { +public abstract class ElementalSprite extends MobSprite { + + protected int boltType; + + protected abstract int texOffset(); + + private Emitter particles; + protected abstract Emitter createEmitter(); public ElementalSprite() { super(); + int c = texOffset(); + texture( Assets.ELEMENTAL ); TextureFilm frames = new TextureFilm( texture, 12, 14 ); idle = new Animation( 10, true ); - idle.frames( frames, 0, 1, 2 ); + idle.frames( frames, c+0, c+1, c+2 ); run = new Animation( 12, true ); - run.frames( frames, 0, 1, 3 ); + run.frames( frames, c+0, c+1, c+3 ); attack = new Animation( 15, false ); - attack.frames( frames, 4, 5, 6 ); + attack.frames( frames, c+4, c+5, c+6 ); + + zap = attack.clone(); die = new Animation( 15, false ); - die.frames( frames, 7, 8, 9, 10, 11, 12, 13, 12 ); + die.frames( frames, c+7, c+8, c+9, c+10, c+11, c+12, c+13, c+12 ); play( idle ); } @@ -52,17 +74,192 @@ public class ElementalSprite extends MobSprite { @Override public void link( Char ch ) { super.link( ch ); - add( State.BURNING ); + + if (particles == null) { + particles = createEmitter(); + } + } + + @Override + public void update() { + super.update(); + + if (particles != null){ + particles.visible = visible; + } } @Override public void die() { super.die(); - remove( State.BURNING ); + if (particles != null){ + particles.on = false; + } } @Override - public int blood() { - return 0xFFFF7D13; + public void kill() { + super.kill(); + if (particles != null){ + particles.killAndErase(); + } + } + + public void zap( int cell ) { + + turnTo( ch.pos , cell ); + play( zap ); + + MagicMissile.boltFromChar( parent, + boltType, + this, + cell, + new Callback() { + @Override + public void call() { + ((Elemental)ch).onZapComplete(); + } + } ); + Sample.INSTANCE.play( Assets.SND_ZAP ); + } + + @Override + public void onComplete( Animation anim ) { + if (anim == zap) { + idle(); + } + super.onComplete( anim ); + } + + public static class Fire extends ElementalSprite { + + { + boltType = MagicMissile.FIRE; + } + + @Override + protected int texOffset() { + return 0; + } + + @Override + protected Emitter createEmitter() { + Emitter emitter = emitter(); + emitter.pour( FlameParticle.FACTORY, 0.06f ); + return emitter; + } + + @Override + public int blood() { + return 0xFFFFBB33; + } + } + + public static class NewbornFire extends ElementalSprite { + + { + boltType = MagicMissile.FIRE; + } + + @Override + protected int texOffset() { + return 14; + } + + @Override + protected Emitter createEmitter() { + Emitter emitter = emitter(); + emitter.pour( ElmoParticle.FACTORY, 0.06f ); + return emitter; + } + + @Override + public int blood() { + return 0xFF85FFC8; + } + } + + public static class Frost extends ElementalSprite { + + { + boltType = MagicMissile.FROST; + } + + @Override + protected int texOffset() { + return 28; + } + + @Override + protected Emitter createEmitter() { + Emitter emitter = emitter(); + emitter.pour( MagicMissile.MagicParticle.FACTORY, 0.06f ); + return emitter; + } + + @Override + public int blood() { + return 0xFF8EE3FF; + } + } + + public static class Shock extends ElementalSprite { + + //different bolt, so overrides zap + @Override + public void zap( int cell ) { + turnTo( ch.pos , cell ); + play( zap ); + + ((Elemental)ch).onZapComplete(); + parent.add( new Beam.LightRay(center(), DungeonTilemap.raisedTileCenterToWorld(cell))); + } + + @Override + protected int texOffset() { + return 42; + } + + @Override + protected Emitter createEmitter() { + Emitter emitter = emitter(); + emitter.pour( SparkParticle.STATIC, 0.06f ); + return emitter; + } + + @Override + public int blood() { + return 0xFFFFFF85; + } + } + + public static class Chaos extends ElementalSprite { + + //no bolt, overrides zap instead + @Override + public void zap( int cell ) { + turnTo( ch.pos , cell ); + play( zap ); + + ((Elemental)ch).onZapComplete(); + Sample.INSTANCE.play( Assets.SND_ZAP ); + } + + @Override + protected int texOffset() { + return 56; + } + + @Override + protected Emitter createEmitter() { + Emitter emitter = emitter(); + emitter.pour( RainbowParticle.BURST, 0.025f ); + return emitter; + } + + @Override + public int blood() { + return 0xFFE3E3E3; + } } } diff --git a/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/actors/actors.properties b/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/actors/actors.properties index 76dcfb5fc..49430f82f 100644 --- a/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/actors/actors.properties +++ b/core/src/main/resources/com/shatteredpixel/shatteredpixeldungeon/messages/actors/actors.properties @@ -476,8 +476,16 @@ actors.mobs.dm300.def_verb=blocked actors.mobs.dm300.rankings_desc=Crushed by the DM-300 actors.mobs.dm300.desc=This machine was created by the Dwarves several centuries ago. Later, Dwarves started to replace machines with golems, elementals and even demons. Eventually it led their civilization to the decline. The DM-300 and similar machines were typically used for construction and mining, and in some cases, for city defense. -actors.mobs.elemental.name=fire elemental -actors.mobs.elemental.desc=Wandering fire elementals are a byproduct of summoning greater entities. They are too chaotic in their nature to be controlled by even the most powerful demonologist. +actors.mobs.elemental$fire.name=fire elemental +actors.mobs.elemental$fire.desc=Elementals are chaotic creatures that are often created when powerful occult magic isn't properly controlled. Elementals have minimal intelligence, and are usually associated with a particular type of magic.\n\nFire elementals are a common type of elemental which deals damage with fiery magic. They will set their target ablaze with melee attacks, and can occasionally shoot bolts of fire as well. +actors.mobs.elemental$newbornfire.name=newborn fire elemental +actors.mobs.elemental$newbornfire.desc=Elementals are chaotic creatures that are often created when powerful occult magic isn't properly controlled. Elementals have minimal intelligence, and are usually associated with a particular type of magic.\n\nFire elementals are a common type of elemental which deals damage with fiery magic. They will set their target ablaze with melee attacks, and can occasionally shoot bolts of fire as well.\n\nThis fire elemental is freshy summoned, and is weakened as a result. In this state it is especially vulnerable to the cold. Its offensive capabilities are still great though, caution is advised. +actors.mobs.elemental$frost.name=frost elemental +actors.mobs.elemental$frost.desc=Elementals are chaotic creatures that are often created when powerful occult magic isn't properly controlled. Elementals have minimal intelligence, and are usually associated with a particular type of magic.\n\nFrost elementals are a common type of elemental which weakens enemies with chilling magic. They will chill their target with melee and occasional ranged attacks. Their magic is much more effective in water. +actors.mobs.elemental$shock.name=shock elemental +actors.mobs.elemental$shock.desc=Elementals are chaotic creatures that are often created when powerful occult magic isn't properly controlled. Elementals have minimal intelligence, and are usually associated with a particular type of magic.\n\nShock elementals are a less common type of elemental which disrupts its enemies with electricity and flashes of light. In melee they will arc electricity to nearby enemies, and deal bonus damage to their primary target if they are in water. They will also occasionally focus a ranged blast of light at their target, temporarily blinding them. +actors.mobs.elemental$chaos.name=chaos elemental +actors.mobs.elemental$chaos.desc=Elementals are chaotic creatures that are often created when powerful occult magic isn't properly controlled. Elementals have minimal intelligence, and are usually associated with a particular type of magic.\n\nChaos elementals are rare and dangerous elementals which haven't stabilized to a particular element. They will unleash wild unpredictable magic when they attack. actors.mobs.eye.name=evil eye actors.mobs.eye.deathgaze_kill=The deathgaze killed you... @@ -547,9 +555,6 @@ actors.mobs.monk.disarm=The monk knocks the %s from your hands! actors.mobs.monk.def_verb=blocked actors.mobs.monk.desc=These monks are fanatics, who devoted themselves to protecting their city's secrets from all aliens. They don't use any armor or weapons, relying solely on the art of hand-to-hand combat. -actors.mobs.newbornelemental.name=newborn fire elemental -actors.mobs.newbornelemental.desc=Fire elementals are a byproduct of summoning greater entities. They are too chaotic in their nature to be controlled by even the most powerful demonologist.\n\nThis fire elemental is freshy summoned, and is weakened as a result. In this state it is especially vulnerable to the cold. Its offensive capabilities are still great though, caution is advised. - actors.mobs.piranha.name=giant piranha actors.mobs.piranha.desc=These carnivorous fish are not natural inhabitants of underground pools. They were bred specifically to protect flooded treasure vaults.