diff --git a/core/src/main/assets/messages/actors/actors.properties b/core/src/main/assets/messages/actors/actors.properties index ea7c5b075..281af9cfe 100644 --- a/core/src/main/assets/messages/actors/actors.properties +++ b/core/src/main/assets/messages/actors/actors.properties @@ -344,8 +344,8 @@ actors.hero.abilities.warrior.shockwave.name=shockwave actors.hero.abilities.warrior.shockwave.desc=The Warrior slams the ground and releases a shockwave in a conical AOE. Enemies caught in the shockwave are damaged and crippled. Consumes 35 energy. actors.hero.abilities.warrior.warrior3.name=??? actors.hero.abilities.warrior.warrior3.desc=I haven't decided on this ability yet. -actors.hero.abilities.mage.moltenearth.name=molten earth -actors.hero.abilities.mage.moltenearth.desc=The Mage casts a spell of molten earth. All the enemies in his field of view will be rooted to the ground and blasted by flames. +actors.hero.abilities.mage.elementalblast.name=elemental blast +actors.hero.abilities.mage.elementalblast.desc=TODO actors.hero.abilities.mage.mage2.name=??? actors.hero.abilities.mage.mage2.desc=I haven't decided on this ability yet. actors.hero.abilities.mage.mage3.name=??? @@ -526,12 +526,12 @@ actors.hero.talent.soul_eater.desc=_+1:_ Soul mark grants _0.33 turns_ of satiet actors.hero.talent.necromancers_minions.title=necromancer's minions actors.hero.talent.necromancers_minions.desc=_+1:_ When a soul marked enemy dies, the Warlock has a _13% chance_ to raise them as a corrupted wraith.\n\n_+2:_ When a soul marked enemy dies, the Warlock has a _27% chance_ to raise them as a corrupted wraith.\n\n_+3:_ When a soul marked enemy dies, the Warlock has a _40% chance_ to raise them as a corrupted wraith. -actors.hero.talent.molten_earth_1.title=TODO NAME -actors.hero.talent.molten_earth_1.desc=TODO DESC -actors.hero.talent.molten_earth_2.title=TODO NAME -actors.hero.talent.molten_earth_2.desc=TODO DESC -actors.hero.talent.molten_earth_3.title=TODO NAME -actors.hero.talent.molten_earth_3.desc=TODO DESC +actors.hero.talent.blast_radius.title=blast radius +actors.hero.talent.blast_radius.desc=_+1:_ Elemental blast's radius is increased to _5 tiles_, from 4.\n\n_+2:_ Elemental blast's radius is increased to _6 tiles_, from 4.\n\n_+3:_ Elemental blast's radius is increased to _7 tiles_, from 4.\n\n_+4:_ Elemental blast's radius is increased to _8 tiles_, from 4. +actors.hero.talent.elemental_blast_2.title=TODO NAME +actors.hero.talent.elemental_blast_2.desc=TODO DESC +actors.hero.talent.elemental_blast_3.title=TODO NAME +actors.hero.talent.elemental_blast_3.desc=TODO DESC actors.hero.talent.mage_2_1.title=TODO NAME actors.hero.talent.mage_2_1.desc=TODO DESC diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Talent.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Talent.java index 928d7cbb9..874df3bee 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Talent.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Talent.java @@ -95,8 +95,8 @@ public enum Talent { EMPOWERED_STRIKE(43, 3), MYSTICAL_CHARGE(44, 3), EXCESS_CHARGE(45, 3), //Warlock T3 SOUL_EATER(46, 3), SOUL_SIPHON(47, 3), NECROMANCERS_MINIONS(48, 3), - //Molten Earth T4 - MOLTEN_EARTH_1(49, 4), MOLTEN_EARTH_2(50, 4), MOLTEN_EARTH_3(51, 4), + //Elemental Blast T4 + BLAST_RADIUS(49, 4), ELEMENTAL_BLAST_2(50, 4), ELEMENTAL_BLAST_3(51, 4), //??? T4 MAGE_2_1(52, 4), MAGE_2_2(53, 4), MAGE_2_3(54, 4), //??? T4 diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/mage/ElementalBlast.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/mage/ElementalBlast.java new file mode 100644 index 000000000..5388fd26f --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/mage/ElementalBlast.java @@ -0,0 +1,166 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2021 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.hero.abilities.mage; + +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.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Roots; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility; +import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile; +import com.shatteredpixel.shatteredpixeldungeon.items.Item; +import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor; +import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand; +import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfBlastWave; +import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfCorrosion; +import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfCorruption; +import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfDisintegration; +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.wands.WandOfLivingEarth; +import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfMagicMissile; +import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfPrismaticLight; +import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfRegrowth; +import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfTransfusion; +import com.shatteredpixel.shatteredpixeldungeon.items.wands.WandOfWarding; +import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff; +import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; +import com.shatteredpixel.shatteredpixeldungeon.mechanics.ConeAOE; +import com.watabou.noosa.audio.Sample; +import com.watabou.utils.Callback; +import com.watabou.utils.Random; + +import java.util.HashMap; + +public class ElementalBlast extends ArmorAbility { + + private static final HashMap, Integer> effectTypes = new HashMap<>(); + static { + effectTypes.put(WandOfMagicMissile.class, MagicMissile.MAGIC_MISS_CONE); + effectTypes.put(WandOfLightning.class, MagicMissile.SPARK_CONE); + effectTypes.put(WandOfDisintegration.class, MagicMissile.PURPLE_CONE); + effectTypes.put(WandOfFireblast.class, MagicMissile.FIRE_CONE); + effectTypes.put(WandOfCorrosion.class, MagicMissile.CORROSION_CONE); + effectTypes.put(WandOfBlastWave.class, MagicMissile.FORCE_CONE); + effectTypes.put(WandOfLivingEarth.class, MagicMissile.EARTH_CONE); + effectTypes.put(WandOfFrost.class, MagicMissile.FROST_CONE); + effectTypes.put(WandOfPrismaticLight.class, MagicMissile.RAINBOW_CONE); + effectTypes.put(WandOfWarding.class, MagicMissile.WARD_CONE); + effectTypes.put(WandOfTransfusion.class, MagicMissile.BLOOD_CONE); + effectTypes.put(WandOfCorruption.class, MagicMissile.SHADOW_CONE); + effectTypes.put(WandOfRegrowth.class, MagicMissile.FOLIAGE_CONE); + } + + @Override + protected void activate(ClassArmor armor, Hero hero, Integer target) { + armor.charge -= chargeUse(hero); + Item.updateQuickslot(); + + Ballistica aim; + //Basically the direction of the aim only matters if it goes outside the map + //So we just ensure it won't do that. + if (hero.pos % Dungeon.level.width() > 10){ + aim = new Ballistica(hero.pos, hero.pos - 1, Ballistica.WONT_STOP); + } else { + aim = new Ballistica(hero.pos, hero.pos + 1, Ballistica.WONT_STOP); + } + + int aoeSize = 4 + hero.pointsInTalent(Talent.BLAST_RADIUS); + + //TODO vary stopping based on wand? e.g. disint should absolutely ignore solid + ConeAOE aoe = new ConeAOE(aim, aoeSize, 360, Ballistica.STOP_SOLID | Ballistica.IGNORE_SOFT_SOLID | Ballistica.STOP_TARGET); + + Class wandCls = null; + if (hero.belongings.getItem(MagesStaff.class) != null) { + wandCls = hero.belongings.getItem(MagesStaff.class).wandClass(); + } + + if (wandCls == null){ + //TODO + return; + } + + for (Ballistica ray : aoe.outerRays){ + ((MagicMissile)hero.sprite.parent.recycle( MagicMissile.class )).reset( + effectTypes.get(wandCls), + hero.sprite, + ray.path.get(ray.dist), + null + ); + } + + //cast a ray 2/3 the way, and do effects + ((MagicMissile)hero.sprite.parent.recycle( MagicMissile.class )).reset( + effectTypes.get(wandCls), + hero.sprite, + aim.path.get(aoeSize / 2), + new Callback() { + @Override + public void call() { + + for (int cell : aoe.cells){ + Char mob = Actor.findChar(cell); + //TODO different effect for each wand + if ( mob != null && mob.alignment != Char.Alignment.ALLY) { + Buff.affect( mob, Burning.class ).reignite( mob ); + Buff.prolong( mob, Roots.class, Roots.DURATION ); + mob.damage(Random.NormalIntRange(4, 16 + Dungeon.depth), new Burning()); + } + } + + //TODO affect hero? + + hero.spendAndNext(Actor.TICK); + } + } + ); + + hero.sprite.operate( hero.pos ); + Invisibility.dispel(); + hero.busy(); + + Sample.INSTANCE.play( Assets.Sounds.CHARGEUP ); + Sample.INSTANCE.play( Assets.Sounds.CHARGEUP ); + + /*for (Mob mob : Dungeon.level.mobs.toArray(new Mob[0])) { + if (Dungeon.level.heroFOV[mob.pos] + && mob.alignment != Char.Alignment.ALLY) { + Buff.affect( mob, Burning.class ).reignite( mob ); + Buff.prolong( mob, Roots.class, Roots.DURATION ); + mob.damage(Random.NormalIntRange(4, 16 + Dungeon.depth), new Burning()); + } + } +*/ + } + + @Override + public Talent[] talents() { + return new Talent[]{Talent.BLAST_RADIUS, Talent.ELEMENTAL_BLAST_2, Talent.ELEMENTAL_BLAST_3, Talent.HEROIC_ENERGY}; + } +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/mage/MoltenEarth.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/mage/MoltenEarth.java deleted file mode 100644 index 225a5af16..000000000 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/mage/MoltenEarth.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Pixel Dungeon - * Copyright (C) 2012-2015 Oleg Dolya - * - * Shattered Pixel Dungeon - * Copyright (C) 2014-2021 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.hero.abilities.mage; - -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.Buff; -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning; -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility; -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Roots; -import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; -import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent; -import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility; -import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; -import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle; -import com.shatteredpixel.shatteredpixeldungeon.items.Item; -import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor; -import com.watabou.noosa.audio.Sample; -import com.watabou.utils.Random; - -public class MoltenEarth extends ArmorAbility { - - @Override - protected void activate(ClassArmor armor, Hero hero, Integer target) { - armor.charge -= 35; - Item.updateQuickslot(); - - for (Mob mob : Dungeon.level.mobs.toArray(new Mob[0])) { - if (Dungeon.level.heroFOV[mob.pos] - && mob.alignment != Char.Alignment.ALLY) { - Buff.affect( mob, Burning.class ).reignite( mob ); - Buff.prolong( mob, Roots.class, Roots.DURATION ); - mob.damage(Random.NormalIntRange(4, 16 + Dungeon.depth), new Burning()); - } - } - - hero.spend( Actor.TICK ); - hero.sprite.operate( hero.pos ); - Invisibility.dispel(); - hero.busy(); - - hero.sprite.emitter().start( ElmoParticle.FACTORY, 0.025f, 20 ); - Sample.INSTANCE.play( Assets.Sounds.BURNING ); - Sample.INSTANCE.play( Assets.Sounds.BURNING ); - Sample.INSTANCE.play( Assets.Sounds.BURNING ); - } - - @Override - public Talent[] talents() { - return new Talent[]{Talent.MOLTEN_EARTH_1, Talent.MOLTEN_EARTH_2, Talent.MOLTEN_EARTH_3, Talent.HEROIC_ENERGY}; - } -} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/MagicMissile.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/MagicMissile.java index 7128e365f..295752d4e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/MagicMissile.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/effects/MagicMissile.java @@ -22,12 +22,15 @@ package com.shatteredpixel.shatteredpixeldungeon.effects; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; +import com.shatteredpixel.shatteredpixeldungeon.effects.particles.BloodParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.CorrosionParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ElmoParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.FlameParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.LeafParticle; +import com.shatteredpixel.shatteredpixeldungeon.effects.particles.PurpleParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.RainbowParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle; +import com.shatteredpixel.shatteredpixeldungeon.effects.particles.SparkParticle; import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap; import com.watabou.noosa.Game; import com.watabou.noosa.Group; @@ -70,9 +73,19 @@ public class MagicMissile extends Emitter { public static final int TOXIC_VENT = 14; public static final int ELMO = 15; + public static final int MAGIC_MISS_CONE = 100; + public static final int FROST_CONE = 101; public static final int FIRE_CONE = 102; + public static final int CORROSION_CONE = 103; public static final int FOLIAGE_CONE = 104; public static final int FORCE_CONE = 105; + public static final int SHADOW_CONE = 107; + public static final int RAINBOW_CONE = 108; + public static final int EARTH_CONE = 109; + public static final int WARD_CONE = 110; + public static final int PURPLE_CONE = 111; + public static final int SPARK_CONE = 112; + public static final int BLOOD_CONE = 113; public void reset( int type, int from, int to, Callback callback ) { reset( type, @@ -175,10 +188,22 @@ public class MagicMissile extends Emitter { pour( ElmoParticle.FACTORY, 0.01f ); break; + case MAGIC_MISS_CONE: + size( 10 ); + pour( WhiteParticle.FACTORY, 0.03f ); + break; + case FROST_CONE: + size( 10 ); + pour( MagicParticle.FACTORY, 0.03f ); + break; case FIRE_CONE: size( 10 ); pour( FlameParticle.FACTORY, 0.03f ); break; + case CORROSION_CONE: + size( 10 ); + pour( CorrosionParticle.MISSILE, 0.03f ); + break; case FOLIAGE_CONE: size( 10 ); pour( LeafParticle.GENERAL, 0.03f ); @@ -187,6 +212,34 @@ public class MagicMissile extends Emitter { size( 10 ); pour( SlowParticle.FACTORY, 0.02f ); break; + case SHADOW_CONE: + size( 10 ); + pour( ShadowParticle.MISSILE, 0.03f ); + break; + case RAINBOW_CONE: + size( 10 ); + pour( RainbowParticle.BURST, 0.03f ); + break; + case EARTH_CONE: + size( 10 ); + pour( EarthParticle.FACTORY, 0.03f ); + break; + case WARD_CONE: + size( 10 ); + pour( WardParticle.FACTORY, 0.03f ); + break; + case PURPLE_CONE: + size( 10 ); + pour( PurpleParticle.MISSILE, 0.03f ); + break; + case SPARK_CONE: + size( 10 ); + pour( SparkParticle.FACTORY, 0.03f ); + break; + case BLOOD_CONE: + size( 10 ); + pour( BloodParticle.FACTORY, 0.03f ); + break; } revive();