v0.9.3: implemented the shockwave ability

This commit is contained in:
Evan Debenham 2021-05-06 16:08:56 -04:00
parent b2ee5f5ac1
commit e6510123f1
6 changed files with 160 additions and 54 deletions

View File

@ -333,11 +333,14 @@ actors.buffs.wellfed.desc=You feel quite satisfied and full.\n\nWhile well fed,
###hero
##abilities
actors.hero.abilities.armorability.self_target=You can't target yourself!
actors.hero.abilities.armorability.prompt=Choose a target
actors.hero.abilities.warrior.heroicleap.name=heroic leap
actors.hero.abilities.warrior.heroicleap.desc=The Warrior performs a heroic leap towards a targeted location, slamming down to stun all neighbouring enemies. Consumes 35 charge.
actors.hero.abilities.warrior.heroicleap.prompt=Choose direction to leap
actors.hero.abilities.warrior.warrior2.name=???
actors.hero.abilities.warrior.warrior2.desc=I haven't decided on this ability yet.
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. Comsumes 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
@ -470,12 +473,12 @@ actors.hero.talent.double_jump.desc=_+1:_ If the Warrior performs a second leap
actors.hero.talent.heroic_leap_4.title=TODO NAME
actors.hero.talent.heroic_leap_4.desc=_+1:_ \n\n_+2:_ \n\n_+3:_ \n\n_+4:_
actors.hero.talent.warrior_2_1.title=TODO NAME
actors.hero.talent.warrior_2_1.desc=TODO DESC
actors.hero.talent.warrior_2_2.title=TODO NAME
actors.hero.talent.warrior_2_2.desc=TODO DESC
actors.hero.talent.warrior_2_3.title=TODO NAME
actors.hero.talent.warrior_2_3.desc=TODO DESC
actors.hero.talent.expanding_wave.title=expanding wave
actors.hero.talent.expanding_wave.desc=_+1:_ Shockwave's range is increased to _6 tiles_ from 5, and its width is increased to _75 degrees_ from 60.\n\n_+2:_ Shockwave's range is increased to _7 tiles_ from 5, and its width is increased to _90 degrees_ from 60.\n\n_+3:_ Shockwave's range is increased to _8 tiles_ from 5, and its width is increased to _105 degrees_ from 60.\n\n_+4:_ Shockwave's range is increased to _9 tiles_ from 5, and its width is increased to _120 degrees_ from 60.
actors.hero.talent.striking_wave.title=striking wave
actors.hero.talent.striking_wave.desc=_+1:_ Damage from shockwave has a _25% chance_ to also trigger on-hit effects like enchantments and combo.\n\n_+2:_ Damage from shockwave has a _50% chance_ to also trigger on-hit effects like enchantments and combo.\n\n_+3:_ Damage from shockwave has a _75% chance_ to also trigger on-hit effects like enchantments and combo.\n\n_+4:_ Shockwave has a _100% chance_ to also trigger on-hit effects like enchantments and combo.
actors.hero.talent.shock_force.title=shock force
actors.hero.talent.shock_force.desc=_+1:_ Shockwave deals _20% more damage_ and has a _25% chance_ to stun instead of cripple.\n\n_+2:_ Shockwave deals _50% more damage_ and has a _50% chance_ to stun instead of cripple.\n\n_+3:_ Shockwave deals _60% more damage_ and has a _75% chance_ to stun instead of cripple.\n\n_+4:_ Shockwave deals _80% more damage_ and has a _100% chance_ to stun instead of cripple.
actors.hero.talent.warrior_2_4.title=TODO NAME
actors.hero.talent.warrior_2_4.desc=TODO DESC

View File

@ -37,7 +37,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.rogue.Rogu
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.rogue.Rogue3;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.rogue.SmokeBomb;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.warrior.HeroicLeap;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.warrior.Warrior2;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.warrior.Shockwave;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.warrior.Warrior3;
import com.shatteredpixel.shatteredpixeldungeon.items.BrokenSeal;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
@ -207,7 +207,7 @@ public enum HeroClass {
public ArmorAbility[] armorAbilities(){
switch (this) {
case WARRIOR: default:
return new ArmorAbility[]{new HeroicLeap(), new Warrior2(), new Warrior3()};
return new ArmorAbility[]{new HeroicLeap(), new Shockwave(), new Warrior3()};
case MAGE:
return new ArmorAbility[]{new MoltenEarth(), new Mage2(), new Mage3()};
case ROGUE:

View File

@ -80,8 +80,8 @@ public enum Talent {
CLEAVE(14, 3), LETHAL_DEFENSE(15, 3), ENHANCED_COMBO(16, 3),
//Heroic Leap T4
BODY_SLAM(17, 4), IMPACT_WAVE(18, 4), DOUBLE_JUMP(19, 4), HEROIC_LEAP_4(20, 4),
//??? T4
WARRIOR_2_1(21, 4), WARRIOR_2_2(22, 4), WARRIOR_2_3(23, 4), WARRIOR_2_4(24, 4),
//Shockwave T4
EXPANDING_WAVE(21, 4), STRIKING_WAVE(22, 4), SHOCK_FORCE(23, 4), WARRIOR_2_4(24, 4),
//??? T4
WARRIOR_3_1(25, 4), WARRIOR_3_2(26, 4), WARRIOR_3_3(27, 4), WARRIOR_3_4(28, 4),

View File

@ -0,0 +1,138 @@
/*
* 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.warrior;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
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.Combo;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Cripple;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
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.mechanics.Ballistica;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.ConeAOE;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.Camera;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Callback;
import com.watabou.utils.Random;
public class Shockwave extends ArmorAbility {
@Override
protected String targetingPrompt() {
return Messages.get(this, "prompt");
}
@Override
protected void activate(ClassArmor armor, Hero hero, Integer target) {
if (target == null){
return;
}
if (target == hero.pos){
GLog.w(Messages.get(this, "self_target"));
return;
}
hero.busy();
//armor.charge -= chargeUse(hero);
Item.updateQuickslot();
Ballistica aim = new Ballistica(hero.pos, target, Ballistica.WONT_STOP);
int maxDist = 5 + hero.pointsInTalent(Talent.EXPANDING_WAVE);
int dist = Math.min(aim.dist, maxDist);
ConeAOE cone = new ConeAOE(aim,
dist,
60 + 15*hero.pointsInTalent(Talent.EXPANDING_WAVE),
Ballistica.STOP_SOLID | Ballistica.STOP_TARGET);
//cast to cells at the tip, rather than all cells, better performance.
for (Ballistica ray : cone.rays){
((MagicMissile)hero.sprite.parent.recycle( MagicMissile.class )).reset(
MagicMissile.FORCE_CONE,
hero.sprite,
ray.path.get(ray.dist),
null
);
}
hero.sprite.zap(target);
Sample.INSTANCE.play(Assets.Sounds.BLAST, 1f, 0.5f);
Camera.main.shake(2, 0.5f);
//final zap at 2/3 distance, for timing of the actual effect
MagicMissile.boltFromChar(hero.sprite.parent,
MagicMissile.FORCE_CONE,
hero.sprite,
cone.coreRay.path.get(dist * 2 / 3),
new Callback() {
@Override
public void call() {
for (int cell : cone.cells){
Char ch = Actor.findChar(cell);
if (ch != null && ch.alignment != hero.alignment){
int damage = Random.NormalIntRange(hero.STR()/2, hero.STR());
damage = Math.round(damage * (1f + 0.15f*hero.pointsInTalent(Talent.SHOCK_FORCE)));
damage -= ch.drRoll();
if (Random.Int(4) < hero.pointsInTalent(Talent.STRIKING_WAVE)){
damage = hero.attackProc(ch, damage);
ch.damage(damage, hero);
if (hero.subClass == HeroSubClass.GLADIATOR){
Buff.affect( hero, Combo.class ).hit( ch );
}
} else {
ch.damage(damage, hero);
}
if (ch.isAlive()){
if (Random.Int(4) < hero.pointsInTalent(Talent.SHOCK_FORCE)){
Buff.affect(ch, Paralysis.class, 5f);
} else {
Buff.affect(ch, Cripple.class, 5f);
}
}
}
}
hero.spendAndNext(Actor.TICK);
}
});
}
@Override
public Talent[] talents() {
return new Talent[]{Talent.EXPANDING_WAVE, Talent.STRIKING_WAVE, Talent.SHOCK_FORCE, Talent.WARRIOR_2_4};
}
}

View File

@ -1,40 +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.warrior;
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.items.armor.ClassArmor;
public class Warrior2 extends ArmorAbility {
@Override
protected void activate(ClassArmor armor, Hero hero, Integer target) {
//TODO
}
@Override
public Talent[] talents() {
return new Talent[]{Talent.WARRIOR_2_1, Talent.WARRIOR_2_2, Talent.WARRIOR_2_3, Talent.WARRIOR_2_4};
}
}

View File

@ -70,8 +70,9 @@ public class MagicMissile extends Emitter {
public static final int TOXIC_VENT = 14;
public static final int ELMO = 15;
public static final int FIRE_CONE = 100;
public static final int FOLIAGE_CONE = 101;
public static final int FIRE_CONE = 102;
public static final int FOLIAGE_CONE = 104;
public static final int FORCE_CONE = 105;
public void reset( int type, int from, int to, Callback callback ) {
reset( type,
@ -182,6 +183,10 @@ public class MagicMissile extends Emitter {
size( 10 );
pour( LeafParticle.GENERAL, 0.03f );
break;
case FORCE_CONE:
size( 10 );
pour( SlowParticle.FACTORY, 0.02f );
break;
}
revive();