v0.9.3: partially implemented the redesigned Elemental Blast ability

This commit is contained in:
Evan Debenham 2021-05-10 21:29:33 -04:00
parent f51475b7d3
commit 393c759104
5 changed files with 229 additions and 83 deletions

View File

@ -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

View File

@ -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

View File

@ -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 <http://www.gnu.org/licenses/>
*/
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<Class<?extends Wand>, 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};
}
}

View File

@ -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 <http://www.gnu.org/licenses/>
*/
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};
}
}

View File

@ -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();