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 extends Wand> 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();