v2.0.0: implemented the elemental strike armor ability and talents
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.1 KiB |
@@ -467,6 +467,10 @@ actors.hero.abilities.duelist.challenge.short_desc=The Duelist _challenges_ a ne
|
||||
actors.hero.abilities.duelist.challenge.desc=The Duelist challenges a nearby enemy to a duel. That enemy is compelled to fight her while all other enemies are temporarily frozen in time.\n\nThe target must be reachable and within 5 tiles of the Duelist. The duel lasts until 10 turns pass, the enemy dies, or the Duelist is more than 5 tiles away from the enemy.\n\nFrozen enemies are invulnerable. The Duelist's allies are not frozen by this ability, but if a boss is targeted its minions will not be frozen either.
|
||||
actors.hero.abilities.duelist.challenge$duelparticipant.name=duel participant
|
||||
actors.hero.abilities.duelist.challenge$duelparticipant.desc=This character is participating in a duel. They, and any of their allies or minions, are allowed to act normally while others are frozen.\n\nThe duel will last for a set amount of time, until one participant dies, or until the participants move more than 5 tiles away from eachother.\n\nTurns remaining: %d.
|
||||
actors.hero.abilities.duelist.elementalstrike.name=elemental strike
|
||||
actors.hero.abilities.duelist.elementalstrike.short_desc=The Duelist performs an _elemental strike_, spreading an effect in a conical AOE based on her weapon enchantment.
|
||||
actors.hero.abilities.duelist.elementalstrike.desc=The Duelist strikes an enemy or location, performing a regular attack that's guaranteed to hit and spreading a magical effect that travels up to 3 tiles in a 65 degree cone. This magical effect varies based on the enchantment on the Duelist's primary weapon.
|
||||
actors.hero.abilities.duelist.elementalstrike.generic_desc=An elemental strike with no enchantment will release a small burst of magic, dealing 5-10 damage to all enemies in range.
|
||||
|
||||
actors.hero.abilities.ratmogrify.name=ratmogrify
|
||||
actors.hero.abilities.ratmogrify.cant_transform=You can't ratmogrify that!
|
||||
@@ -870,7 +874,12 @@ actors.hero.talent.invigorating_victory.desc=_+1:_ If the Duelist defeats her ta
|
||||
actors.hero.talent.elimination_match.title=elimination match
|
||||
actors.hero.talent.elimination_match.desc=_+1:_ If the Duelist challenges again within 3 turns of a duel ending, that challenge has a _20% reduced_ charge cost.\n\n_+2:_ If the Duelist challenges again within 3 turns of a duel ending, that challenge has a _36% reduced_ charge cost.\n\n_+3:_ If the Duelist challenges again within 3 turns of a duel ending, that challenge has a _50% reduced_ charge cost.\n\n_+4:_ If the Duelist challenges again within 3 turns of a duel ending, that challenge has a _60% reduced_ charge cost.
|
||||
|
||||
#second armor ability
|
||||
actors.hero.talent.elemental_reach.title=elemental reach
|
||||
actors.hero.talent.elemental_reach.desc=_+1:_ Elemental strike's range is increased to _4 tiles_ from 3, and its width is increased to _70 degrees_ from 65.\n\n_+2:_ Elemental strike's range is increased to _5 tiles_ from 3, and its width is increased to _75 degrees_ from 65.\n\n_+3:_ Elemental strike's range is increased to _6 tiles_ from 3, and its width is increased to _80 degrees_ from 65.\n\n_+4:_ Elemental strike's range is increased to _7 tiles_ from 3, and its width is increased to _85 degrees_ from 65.
|
||||
actors.hero.talent.striking_force.title=striking force
|
||||
actors.hero.talent.striking_force.desc=_+1:_ The power of elemental strike's effect is increased by _25%_.\n\n_+2:_ The power of elemental strike's effect is increased by _50%_.\n\n_+3:_ The power of elemental strike's effect is increased by _75%_.\n\n_+4:_ The power of elemental strike's effect is increased by _100%_.
|
||||
actors.hero.talent.directed_power.title=directed power
|
||||
actors.hero.talent.directed_power.desc=_+1:_ The direct attack from elemental strike gains _+25% enchantment power_ for each enemy in range of elemental strike's effect, including the attack target.\n\n_+2:_ The direct attack from elemental strike gains _+50% enchantment power_ for each enemy in range of elemental strike's effect, including the attack target.\n\n_+3:_ The direct attack from elemental strike gains _+75% enchantment power_ for each enemy in range of elemental strike's effect, including the attack target.\n\n_+4:_ The direct attack from elemental strike gains _+100% enchantment power_ for each enemy in range of elemental strike's effect, including the attack target.
|
||||
|
||||
#third armor ability
|
||||
|
||||
|
||||
@@ -1406,12 +1406,15 @@ items.weapon.curses.annoying.msg_11=I didn't want to be a weapon, I wanted to be
|
||||
items.weapon.curses.annoying.msg_12=Remember, overconfidence is a slow and insidious killer.
|
||||
items.weapon.curses.annoying.msg_13=ALL YOUR BASE ARE BELONG TO US!
|
||||
items.weapon.curses.annoying.desc=Annoying weapons are capable of speech, but they're a bit too energetic. They will often draw attention to you without meaning to.
|
||||
items.weapon.curses.annoying.elestrike_desc=An elemental strike with an annoying curse has a 20% chance to amok each enemy in range for 5 turns.
|
||||
|
||||
items.weapon.curses.dazzling.name=dazzling %s
|
||||
items.weapon.curses.dazzling.desc=Dazzling weapons will sometimes flash with dazzling light, blinding everything that can see them.
|
||||
items.weapon.curses.dazzling.elestrike_desc=An elemental strike with a dazzling curse has a 50% chance to blind each enemy in range for 5 turns.
|
||||
|
||||
items.weapon.curses.displacing.name=displacing %s
|
||||
items.weapon.curses.displacing.desc=Displacing weapons are infused with chaotic teleportation magic, possessing the ability to warp enemies around the floor randomly.
|
||||
items.weapon.curses.displacing.elestrike_desc=An elemental strike with a displacing curse has a 50% chance to teleport each enemy in range.
|
||||
|
||||
items.weapon.curses.explosive.name=explosive %s
|
||||
items.weapon.curses.explosive.warm=Warm...
|
||||
@@ -1420,67 +1423,82 @@ items.weapon.curses.explosive.desc=Explosive weapons steadily build up power and
|
||||
items.weapon.curses.explosive.desc_cool=Your weapon is currently cool to the touch.
|
||||
items.weapon.curses.explosive.desc_warm=Your weapon is building energy and getting warm...
|
||||
items.weapon.curses.explosive.desc_hot=Your weapon is hot! It's about to explode!
|
||||
items.weapon.curses.explosive.elestrike_desc=An elemental strike with an explosive curse has a 50% chance to cause an explosion to appear on a random enemy in range.
|
||||
|
||||
items.weapon.curses.friendly.name=friendly %s
|
||||
items.weapon.curses.friendly.desc=Friendly weapons are best suited for pacifists, occasionally triggering magic that makes it impossible to fight.
|
||||
items.weapon.curses.friendly.elestrike_desc=An elemental strike with a friendly curse has a 50% chance to charm each enemy in range for 5 turns.
|
||||
|
||||
items.weapon.curses.polarized.name=polarized %s
|
||||
items.weapon.curses.polarized.desc=A polarized weapon is affected by magic that causes its attack to either deal 50% more damage, or no damage at all.
|
||||
items.weapon.curses.polarized.elestrike_desc=An elemental strike with a polarized curse has a 50% chance to deal 20-30 damage to each enemy in range.
|
||||
|
||||
items.weapon.curses.sacrificial.name=sacrificial %s
|
||||
items.weapon.curses.sacrificial.desc=Sacrificial weapons will demand blood from the wearer in return for attacking foes. The more healthy the wearer is, the more blood the curse will take.
|
||||
items.weapon.curses.sacrificial.elestrike_desc=An elemental strike with a sacrificial curse causes the hero and each enemy in range to bleed for 10 HP.
|
||||
|
||||
items.weapon.curses.wayward.name=wayward %s
|
||||
items.weapon.curses.wayward.desc=Wayward weapons will sometimes become extremely inaccurate. This magic lasts for a little while when it activates, but can be dispelled by landing a blow with the wayward weapon.
|
||||
items.weapon.curses.wayward.elestrike_desc=An elemental strike with a wayward curse has a 50% chance to hex each enemy in range for 5 turns.
|
||||
items.weapon.curses.wayward$waywardbuff.name=wayward
|
||||
items.weapon.curses.wayward$waywardbuff.desc=Your wayward weapon's magic has activated, making it extremely inaccurate for a short time. Note that this does not affect attacks which are guaranteed to hit, such as surprise attacks. Successfully attacking with the wayward weapon will clear this effect immediately.\n\nTurns remaining: %s.
|
||||
|
||||
###enchantments
|
||||
items.weapon.enchantments.blazing.name=blazing %s
|
||||
items.weapon.enchantments.blazing.desc=This enchantment causes flames to spit forth from a weapon, igniting enemies and dealing bonus damage to enemies that are already aflame.
|
||||
items.weapon.enchantments.blazing.elestrike_desc=An elemental strike with a blazing enchantment spreads fire to every tile in range, which lasts 6 turns.
|
||||
|
||||
items.weapon.enchantments.blocking.name=blocking %s
|
||||
items.weapon.enchantments.blocking.desc=Blocking weapons have a chance to briefly shield you after attacking with them.
|
||||
items.weapon.enchantments.blocking.elestrike_desc=An elemental strike with a blocking enchantment grants the Duelist an extra 5 shielding for each enemy in range.
|
||||
items.weapon.enchantments.blocking$blockbuff.name=blocking
|
||||
items.weapon.enchantments.blocking$blockbuff.desc=Your weapon's blocking enchantment has granted you a brief boost to your defensive power!\n\nShielding remaining: %d\n\nTurns remaining: %s.
|
||||
|
||||
items.weapon.enchantments.blooming.name=blooming %s
|
||||
items.weapon.enchantments.blooming.desc=Blooming weapons contain magic which will cause vegetation to sprout on or around those struck by them.
|
||||
items.weapon.enchantments.blooming.elestrike_desc=An elemental strike with a blooming enchantment spreads grass to up to 6 tiles in range, and roots all enemies in range for 5 turns.
|
||||
|
||||
items.weapon.enchantments.chilling.name=chilling %s
|
||||
items.weapon.enchantments.chilling.desc=Enemies struck with this enchantment are chilled, slowing their movement and attacks.
|
||||
items.weapon.enchantments.chilling.elestrike_desc=An elemental strike with a chilling enchantment spreads chilling air to every tile in range, which lasts 6 turns.
|
||||
|
||||
items.weapon.enchantments.kinetic.name=kinetic %s
|
||||
items.weapon.enchantments.kinetic.desc=When an enemy is killed with a kinetic weapon, any excess force is stored in the weapon and will be applied to the next successful attack.
|
||||
items.weapon.enchantments.kinetic.elestrike_desc=An elemental strike with a kinetic enchantment applies 33% of stored damage to each enemy in range, except the primary target.
|
||||
items.weapon.enchantments.kinetic$conserveddamage.name=conserved damage
|
||||
items.weapon.enchantments.kinetic$conserveddamage.desc=Your weapon has stored the excess force from a previous killing blow, and will apply it as bonus damage to your next attack. The energy will slowly fade over time, however.\n\nConserved Damage: %d.
|
||||
|
||||
items.weapon.enchantments.corrupting.name=corrupting %s
|
||||
items.weapon.enchantments.corrupting.desc=This powerful enchantment possesses the ability to turn enemies to your will. When an enemy is killed with this weapon, there is a chance they will become corrupted instead of dying.
|
||||
items.weapon.enchantments.corrupting.elestrike_desc=An elemental strike with a corrupting enchantment has a 4-20% chance (based on missing HP) to corrupt each enemy in range, except the primary target.
|
||||
|
||||
items.weapon.enchantments.elastic.name=elastic %s
|
||||
items.weapon.enchantments.elastic.desc=Elastic weapons have a chance to send enemies flying back short distances.
|
||||
items.weapon.enchantments.elastic.elestrike_desc=An elemental strike with an elastic enchantment knocks all enemies in range back 4 tiles.
|
||||
|
||||
items.weapon.enchantments.grim.name=grim %s
|
||||
items.weapon.enchantments.grim.desc=This powerful enchantment possesses the power to instantly execute an enemy. The effect is more likely to occur the weaker the enemy is.
|
||||
items.weapon.enchantments.grim.elestrike_desc=An elemental strike with a grim enchantment has up to a 6-30% chance (based on missing HP) to kill each enemy in range, except the primary target.
|
||||
|
||||
items.weapon.enchantments.lucky.name=lucky %s
|
||||
items.weapon.enchantments.lucky.desc=Enemies which are killed by a lucky weapon have a chance to drop extra loot.
|
||||
|
||||
items.weapon.enchantments.precise.name=precise %s
|
||||
items.weapon.enchantments.precise.desc=A precise weapon has a chance to guarantee a hit on an enemy, regardless of the circumstances.
|
||||
items.weapon.enchantments.lucky.elestrike_desc=An elemental strike with a lucky enchantment has a 10% chance to spawn loot under each enemy in range. This effect can only trigger once per enemy.
|
||||
|
||||
items.weapon.enchantments.projecting.name=projecting %s
|
||||
items.weapon.enchantments.projecting.desc=With this enchantment melee weapons will gain extra reach. Ranged weapons will be able to penetrate nearby walls.
|
||||
items.weapon.enchantments.projecting.elestrike_desc=An elemental strike with a projecting enchantment deals 25% damage to each enemy in range, except the primary target.
|
||||
|
||||
items.weapon.enchantments.shocking.name=shocking %s
|
||||
items.weapon.enchantments.shocking.desc=Electricity arcs from a shocking weapon, dealing extra damage to all nearby enemies.
|
||||
items.weapon.enchantments.shocking.elestrike_desc=An elemental strike with a shocking enchantment spreads electricity to every tile in range, which lasts 6 turns.
|
||||
|
||||
items.weapon.enchantments.unstable.name=unstable %s
|
||||
items.weapon.enchantments.unstable.desc=This enchantment radiates chaotic energy, acting as a different enchantment with each hit.
|
||||
items.weapon.enchantments.unstable.elestrike_desc=An elemental strike with an unstable enchantment applies a random enchantment effect to each enemy in range, except the primary target.
|
||||
|
||||
items.weapon.enchantments.vampiric.name=vampiric %s
|
||||
items.weapon.enchantments.vampiric.desc=This powerful enchantment leeches life force from enemies with each blow, funneling it back into the wearer. The effect is stronger the lower the wearer's health.
|
||||
items.weapon.enchantments.vampiric.elestrike_desc=An elemental strike with a vampiric enchantment heals the Duelist for 2 HP for each enemy in range.
|
||||
|
||||
|
||||
###melee weapons
|
||||
|
||||
+2
-1
@@ -29,6 +29,7 @@ import com.shatteredpixel.shatteredpixeldungeon.QuickSlot;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.SPDSettings;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.duelist.Challenge;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.duelist.ElementalStrike;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.NaturesPower;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.SpiritHawk;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.SpectralBlades;
|
||||
@@ -253,7 +254,7 @@ public enum HeroClass {
|
||||
case HUNTRESS:
|
||||
return new ArmorAbility[]{new SpectralBlades(), new NaturesPower(), new SpiritHawk()};
|
||||
case DUELIST:
|
||||
return new ArmorAbility[]{new Challenge()};
|
||||
return new ArmorAbility[]{new Challenge(), new ElementalStrike()};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ public enum Talent {
|
||||
//Duelist A1 T4
|
||||
CLOSE_THE_GAP(145, 4), INVIGORATING_VICTORY(146, 4), ELIMINATION_MATCH(147, 4),
|
||||
//Duelist A2 T4
|
||||
DUELIST_A2_1(148, 4), DUELIST_A2_2(149, 4), DUELIST_A2_3(150, 4),
|
||||
ELEMENTAL_REACH(148, 4), STRIKING_FORCE(149, 4), DIRECTED_POWER(150, 4),
|
||||
//Duelist A3 T4
|
||||
DUELIST_A3_1(151, 4), DUELIST_A3_2(152, 4), DUELIST_A3_3(153, 4),
|
||||
|
||||
|
||||
+532
@@ -0,0 +1,532 @@
|
||||
/*
|
||||
* Pixel Dungeon
|
||||
* Copyright (C) 2012-2015 Oleg Dolya
|
||||
*
|
||||
* Shattered Pixel Dungeon
|
||||
* Copyright (C) 2014-2023 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.duelist;
|
||||
|
||||
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.blobs.Blob;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Electricity;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Fire;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Freezing;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.AllyBuff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Amok;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Barrier;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Bleeding;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Blindness;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Charm;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Corruption;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FlavourBuff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Hex;
|
||||
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.hero.abilities.mage.ElementalBlast;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.KindOfWeapon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.bombs.Bomb;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTeleportation;
|
||||
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.weapon.Weapon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.curses.Annoying;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.curses.Dazzling;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.curses.Displacing;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.curses.Explosive;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.curses.Friendly;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.curses.Polarized;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.curses.Sacrificial;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.curses.Wayward;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Blazing;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Blocking;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Blooming;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Chilling;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Corrupting;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Elastic;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Grim;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Kinetic;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Lucky;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Projecting;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Shocking;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Unstable;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Vampiric;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MeleeWeapon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.mechanics.ConeAOE;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.AttackIndicator;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.HeroIcon;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.noosa.audio.Sample;
|
||||
import com.watabou.utils.Callback;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ElementalStrike extends ArmorAbility {
|
||||
|
||||
//TODO a few duplicates here (curse duplicates are fine)
|
||||
private static final HashMap<Class<?extends Weapon.Enchantment>, Integer> effectTypes = new HashMap<>();
|
||||
static {
|
||||
effectTypes.put(Blazing.class, MagicMissile.FIRE_CONE);
|
||||
effectTypes.put(Chilling.class, MagicMissile.FROST_CONE);
|
||||
effectTypes.put(Kinetic.class, MagicMissile.FORCE_CONE);
|
||||
effectTypes.put(Shocking.class, MagicMissile.SPARK_CONE);
|
||||
effectTypes.put(Blocking.class, MagicMissile.WARD_CONE);
|
||||
effectTypes.put(Blooming.class, MagicMissile.FOLIAGE_CONE);
|
||||
effectTypes.put(Elastic.class, MagicMissile.FORCE_CONE);
|
||||
effectTypes.put(Lucky.class, MagicMissile.RAINBOW_CONE);
|
||||
effectTypes.put(Projecting.class, MagicMissile.PURPLE_CONE);
|
||||
effectTypes.put(Unstable.class, MagicMissile.RAINBOW_CONE);
|
||||
effectTypes.put(Corrupting.class, MagicMissile.SHADOW_CONE);
|
||||
effectTypes.put(Grim.class, MagicMissile.SHADOW_CONE);
|
||||
effectTypes.put(Vampiric.class, MagicMissile.BLOOD_CONE);
|
||||
|
||||
effectTypes.put(Annoying.class, MagicMissile.SHADOW_CONE);
|
||||
effectTypes.put(Displacing.class, MagicMissile.SHADOW_CONE);
|
||||
effectTypes.put(Dazzling.class, MagicMissile.SHADOW_CONE);
|
||||
effectTypes.put(Explosive.class, MagicMissile.SHADOW_CONE);
|
||||
effectTypes.put(Sacrificial.class, MagicMissile.SHADOW_CONE);
|
||||
effectTypes.put(Wayward.class, MagicMissile.SHADOW_CONE);
|
||||
effectTypes.put(Polarized.class, MagicMissile.SHADOW_CONE);
|
||||
effectTypes.put(Friendly.class, MagicMissile.SHADOW_CONE);
|
||||
|
||||
effectTypes.put(null, MagicMissile.MAGIC_MISS_CONE);
|
||||
}
|
||||
|
||||
{
|
||||
baseChargeUse = 25;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String targetingPrompt() {
|
||||
return Messages.get(this, "prompt");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int targetedPos(Char user, int dst) {
|
||||
return dst;
|
||||
}
|
||||
|
||||
//3 tiles in a 65 degree cone
|
||||
// boostable to 4/5/6/7 tiles in a 70/75/80/85 degree cone
|
||||
|
||||
@Override
|
||||
protected void activate(ClassArmor armor, Hero hero, Integer target) {
|
||||
if (target == null){
|
||||
return;
|
||||
}
|
||||
|
||||
armor.charge -= chargeUse(hero);
|
||||
Item.updateQuickslot();
|
||||
|
||||
Ballistica aim = new Ballistica(hero.pos, target, Ballistica.WONT_STOP);
|
||||
|
||||
int maxDist = 3 + hero.pointsInTalent(Talent.ELEMENTAL_REACH);
|
||||
int dist = Math.min(aim.dist, maxDist);
|
||||
|
||||
ConeAOE cone = new ConeAOE(aim,
|
||||
dist,
|
||||
65 + 5*hero.pointsInTalent(Talent.ELEMENTAL_REACH),
|
||||
Ballistica.STOP_SOLID | Ballistica.STOP_TARGET);
|
||||
|
||||
KindOfWeapon w = hero.belongings.weapon();
|
||||
Weapon.Enchantment enchantment = ((MeleeWeapon) w).enchantment;
|
||||
Class<?extends Weapon.Enchantment> enchCls = null;
|
||||
if (enchantment != null){
|
||||
enchCls = enchantment.getClass();
|
||||
}
|
||||
|
||||
//cast to cells at the tip, rather than all cells, better performance.
|
||||
for (Ballistica ray : cone.outerRays){
|
||||
((MagicMissile)hero.sprite.parent.recycle( MagicMissile.class )).reset(
|
||||
effectTypes.get(enchCls),
|
||||
hero.sprite,
|
||||
ray.path.get(ray.dist),
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
hero.sprite.attack(target, new Callback() {
|
||||
@Override
|
||||
public void call() {
|
||||
|
||||
Char enemy = Actor.findChar(target);
|
||||
|
||||
if (enemy != null) {
|
||||
if (hero.isCharmedBy(enemy)) {
|
||||
enemy = null;
|
||||
} else if (enemy.alignment == hero.alignment) {
|
||||
enemy = null;
|
||||
} else if (!hero.canAttack(enemy)) {
|
||||
enemy = null;
|
||||
}
|
||||
}
|
||||
|
||||
preAttackEffect(cone, hero, enchantment);
|
||||
|
||||
if (enemy != null){
|
||||
AttackIndicator.target(enemy);
|
||||
if (hero.attack(enemy, 1, 0, Char.INFINITE_ACCURACY)) {
|
||||
Sample.INSTANCE.play(Assets.Sounds.HIT_STRONG);
|
||||
}
|
||||
}
|
||||
|
||||
perCellEffect(cone, enchantment);
|
||||
|
||||
perCharEffect(cone, hero, enemy, enchantment);
|
||||
|
||||
Invisibility.dispel();
|
||||
hero.spendAndNext(hero.attackDelay());
|
||||
}
|
||||
});
|
||||
|
||||
Sample.INSTANCE.play(Assets.Sounds.CHARGEUP);
|
||||
hero.busy();
|
||||
|
||||
}
|
||||
|
||||
//effects that trigger before the attack
|
||||
private void preAttackEffect(ConeAOE cone, Hero hero, Weapon.Enchantment ench){
|
||||
|
||||
int targetsHit = 0;
|
||||
for (Char ch : Actor.chars()){
|
||||
if (ch.alignment == Char.Alignment.ENEMY && cone.cells.contains(ch.pos)){
|
||||
targetsHit++;
|
||||
}
|
||||
}
|
||||
|
||||
if (hero.hasTalent(Talent.DIRECTED_POWER)){
|
||||
float enchBoost = 0.25f * targetsHit * hero.pointsInTalent(Talent.DIRECTED_POWER);
|
||||
Buff.affect(hero, DirectedPowerTracker.class, 0f).enchBoost = enchBoost;
|
||||
}
|
||||
|
||||
float powerMulti = 1f + 0.25f*Dungeon.hero.pointsInTalent(Talent.STRIKING_FORCE);
|
||||
|
||||
//*** Kinetic ***
|
||||
if (ench instanceof Kinetic){
|
||||
if (hero.buff(Kinetic.KineticTracker.class) != null) {
|
||||
storedKineticDamage = hero.buff(Kinetic.KineticTracker.class).conservedDamage;
|
||||
}
|
||||
|
||||
//*** Blocking ***
|
||||
} else if (ench instanceof Blocking){
|
||||
if (targetsHit > 0){
|
||||
Buff.affect(hero, Barrier.class).setShield(Math.round(5f*targetsHit*powerMulti));
|
||||
}
|
||||
|
||||
//*** Vampiric ***
|
||||
} else if (ench instanceof Vampiric){
|
||||
if (targetsHit > 0){
|
||||
int heal = Math.round(2f*targetsHit*powerMulti);
|
||||
heal = Math.min( heal, hero.HT - hero.HP );
|
||||
if (heal > 0){
|
||||
hero.HP += heal;
|
||||
hero.sprite.emitter().start( Speck.factory( Speck.HEALING ), 0.4f, 1 );
|
||||
hero.sprite.showStatus( CharSprite.POSITIVE, Integer.toString( heal ) );
|
||||
}
|
||||
}
|
||||
|
||||
//*** Sacrificial ***
|
||||
} else if (ench instanceof Sacrificial){
|
||||
Buff.affect(hero, Bleeding.class).set(10 * powerMulti);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class DirectedPowerTracker extends FlavourBuff{
|
||||
public float enchBoost = 0f;
|
||||
}
|
||||
|
||||
public static class ElementalStrikeLuckyTracker extends Buff{};
|
||||
|
||||
private int storedKineticDamage = 0;
|
||||
|
||||
//effects that affect the cells of the environment themselves
|
||||
private void perCellEffect(ConeAOE cone, Weapon.Enchantment ench){
|
||||
|
||||
float powerMulti = 1f + 0.25f*Dungeon.hero.pointsInTalent(Talent.STRIKING_FORCE);
|
||||
|
||||
//*** Blazing ***
|
||||
if (ench instanceof Blazing){
|
||||
for (int cell : cone.cells) {
|
||||
GameScene.add(Blob.seed(cell, Math.round(6 * powerMulti), Fire.class));
|
||||
}
|
||||
|
||||
//*** Chilling ***
|
||||
} else if (ench instanceof Chilling){
|
||||
for (int cell : cone.cells) {
|
||||
GameScene.add(Blob.seed(cell, Math.round(6 * powerMulti), Freezing.class));
|
||||
}
|
||||
|
||||
//*** Shocking ***
|
||||
} else if (ench instanceof Shocking){
|
||||
for (int cell : cone.cells) {
|
||||
GameScene.add(Blob.seed(cell, Math.round(6 * powerMulti), Electricity.class));
|
||||
}
|
||||
|
||||
//*** Blooming ***
|
||||
} else if (ench instanceof Blooming){
|
||||
ArrayList<Integer> cells = new ArrayList<>(cone.cells);
|
||||
Random.shuffle(cells);
|
||||
int grassToPlace = Math.round(6*powerMulti);
|
||||
|
||||
for (int cell : cells) {
|
||||
int terr = Dungeon.level.map[cell];
|
||||
if (terr == Terrain.EMPTY || terr == Terrain.EMBERS || terr == Terrain.EMPTY_DECO ||
|
||||
terr == Terrain.GRASS) {
|
||||
if (grassToPlace > 0){
|
||||
Level.set(cell, Terrain.HIGH_GRASS);
|
||||
grassToPlace--;
|
||||
} else {
|
||||
Level.set(cell, Terrain.GRASS);
|
||||
}
|
||||
GameScene.updateMap( cell );
|
||||
}
|
||||
}
|
||||
Dungeon.observe();
|
||||
}
|
||||
}
|
||||
|
||||
//effects that affect the characters within the cone AOE
|
||||
private void perCharEffect(ConeAOE cone, Hero hero, Char primaryTarget, Weapon.Enchantment ench) {
|
||||
|
||||
float powerMulti = 1f + 0.25f * Dungeon.hero.pointsInTalent(Talent.STRIKING_FORCE);
|
||||
|
||||
ArrayList<Char> affected = new ArrayList<>();
|
||||
|
||||
for (Char ch : Actor.chars()) {
|
||||
if (ch.alignment != Char.Alignment.ALLY && cone.cells.contains(ch.pos)) {
|
||||
affected.add(ch);
|
||||
}
|
||||
}
|
||||
|
||||
//*** no enchantment ***
|
||||
if (ench == null) {
|
||||
for (Char ch : affected){
|
||||
ch.damage(Math.round(powerMulti*Random.NormalIntRange(5, 10)), ElementalStrike.this);
|
||||
}
|
||||
|
||||
//*** Kinetic ***
|
||||
} else if (ench instanceof Kinetic){
|
||||
for (Char ch : affected){
|
||||
if (ch != primaryTarget) {
|
||||
ch.damage(Math.round(storedKineticDamage * 0.33f * powerMulti), ench);
|
||||
}
|
||||
}
|
||||
|
||||
//*** Blooming ***
|
||||
} else if (ench instanceof Blooming){
|
||||
for (Char ch : affected){
|
||||
Buff.affect(ch, Roots.class, Math.round(5f*powerMulti));
|
||||
}
|
||||
|
||||
//*** Elastic ***
|
||||
} else if (ench instanceof Elastic){
|
||||
//TODO sort affected by distance first? So further ones get knocked back first
|
||||
for (Char ch : affected){
|
||||
Ballistica aim = new Ballistica(hero.pos, ch.pos, Ballistica.WONT_STOP);
|
||||
int knockback = Math.round(4*powerMulti);
|
||||
WandOfBlastWave.throwChar(ch,
|
||||
new Ballistica(ch.pos, aim.collisionPos, Ballistica.MAGIC_BOLT),
|
||||
knockback,
|
||||
true,
|
||||
true,
|
||||
ElementalStrike.this.getClass());
|
||||
}
|
||||
|
||||
//*** Lucky ***
|
||||
} else if (ench instanceof Lucky){
|
||||
for (Char ch : affected){
|
||||
if (Random.Float() < 0.1f*powerMulti &&
|
||||
ch.buff(ElementalStrikeLuckyTracker.class) == null) {
|
||||
Dungeon.level.drop(Lucky.genLoot(), ch.pos).sprite.drop();
|
||||
Lucky.showFlare(ch.sprite);
|
||||
Buff.affect(ch, ElementalStrikeLuckyTracker.class);
|
||||
}
|
||||
}
|
||||
|
||||
//*** Projecting ***
|
||||
} else if (ench instanceof Projecting){
|
||||
for (Char ch : affected){
|
||||
if (ch != primaryTarget) {
|
||||
ch.damage(Math.round(hero.damageRoll() * 0.25f * powerMulti), ench);
|
||||
}
|
||||
}
|
||||
|
||||
//*** Unstable ***
|
||||
} else if (ench instanceof Unstable){
|
||||
KindOfWeapon w = hero.belongings.weapon();
|
||||
if (w instanceof Weapon) {
|
||||
for (Char ch : affected){
|
||||
if (ch != primaryTarget) {
|
||||
ench.proc((Weapon) w, hero, ch, w.damageRoll(hero));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*** Corrupting ***
|
||||
} else if (ench instanceof Corrupting){
|
||||
for (Char ch : affected){
|
||||
if (ch != primaryTarget
|
||||
&& !ch.isImmune(Corruption.class)
|
||||
&& ch.buff(Corruption.class) == null
|
||||
&& ch instanceof Mob
|
||||
&& ch.isAlive()) {
|
||||
float hpMissing = 1f - (ch.HP / (float)ch.HT);
|
||||
if (Random.Float() < 0.2f*powerMulti*hpMissing){
|
||||
Corruption.corruptionHeal(ch);
|
||||
AllyBuff.affectAndLoot((Mob) ch, hero, Corruption.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*** Grim ***
|
||||
} else if (ench instanceof Grim){
|
||||
for (Char ch : affected){
|
||||
if (ch != primaryTarget) {
|
||||
float hpMissing = 1f - (ch.HP / (float)ch.HT);
|
||||
if (Random.Float() < 0.3f*powerMulti*hpMissing){
|
||||
ch.damage( ch.HP, Grim.class );
|
||||
ch.sprite.emitter().burst( ShadowParticle.UP, 5 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*** Annoying ***
|
||||
} else if (ench instanceof Annoying){
|
||||
for (Char ch : affected){
|
||||
if (Random.Float() < 0.1f*powerMulti){
|
||||
//TODO totally should add a bit of dialogue here
|
||||
Buff.affect(ch, Amok.class, 5f);
|
||||
}
|
||||
}
|
||||
|
||||
//*** Displacing ***
|
||||
} else if (ench instanceof Displacing){
|
||||
for (Char ch : affected){
|
||||
if (Random.Float() < 0.5f*powerMulti){
|
||||
int oldpos = ch.pos;
|
||||
if (ScrollOfTeleportation.teleportChar(ch)){
|
||||
if (Dungeon.level.heroFOV[oldpos]) {
|
||||
CellEmitter.get( oldpos ).start( Speck.factory( Speck.LIGHT ), 0.2f, 3 );
|
||||
}
|
||||
|
||||
if (ch instanceof Mob && ((Mob) ch).state == ((Mob) ch).HUNTING){
|
||||
((Mob) ch).state = ((Mob) ch).WANDERING;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*** Dazzling ***
|
||||
} else if (ench instanceof Dazzling){
|
||||
for (Char ch : affected){
|
||||
if (Random.Float() < 0.5f*powerMulti){
|
||||
Buff.affect(ch, Blindness.class, 5f);
|
||||
}
|
||||
}
|
||||
|
||||
//*** Explosive ***
|
||||
} else if (ench instanceof Explosive){
|
||||
if (Random.Float() < 0.5f*powerMulti){
|
||||
Char exploding = Random.element(affected);
|
||||
if (exploding != null) new Bomb.MagicalBomb().explode(exploding.pos);
|
||||
}
|
||||
|
||||
//*** Sacrificial ***
|
||||
} else if (ench instanceof Sacrificial){
|
||||
for (Char ch : affected){
|
||||
Buff.affect(ch, Bleeding.class).set(10f*powerMulti);
|
||||
}
|
||||
|
||||
//*** Wayward ***
|
||||
} else if (ench instanceof Wayward){
|
||||
for (Char ch : affected){
|
||||
if (Random.Float() < 0.5f*powerMulti){
|
||||
Buff.affect(ch, Hex.class, 5f);
|
||||
}
|
||||
}
|
||||
|
||||
//*** Polarized ***
|
||||
} else if (ench instanceof Polarized){
|
||||
for (Char ch : affected){
|
||||
if (Random.Float() < 0.5f*powerMulti){
|
||||
ch.damage(Random.NormalIntRange(20, 30), ElementalStrike.this);
|
||||
}
|
||||
}
|
||||
|
||||
//*** Friendly ***
|
||||
} else if (ench instanceof Friendly){
|
||||
for (Char ch : affected){
|
||||
if (Random.Float() < 0.5f*powerMulti){
|
||||
Buff.affect(ch, Charm.class, 5f).target = hero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String desc() {
|
||||
String desc = Messages.get(this, "desc");
|
||||
if (Game.scene() instanceof GameScene){
|
||||
KindOfWeapon w = Dungeon.hero.belongings.weapon();
|
||||
if (w instanceof MeleeWeapon && ((MeleeWeapon) w).enchantment != null){
|
||||
desc += "\n\n" + Messages.get(((MeleeWeapon) w).enchantment, "elestrike_desc");
|
||||
} else {
|
||||
desc += "\n\n" + Messages.get(this, "generic_desc");
|
||||
}
|
||||
} else {
|
||||
desc += "\n\n" + Messages.get(this, "generic_desc");
|
||||
}
|
||||
desc += "\n\n" + Messages.get(this, "cost", (int)baseChargeUse);
|
||||
return desc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int icon() {
|
||||
return HeroIcon.ELEMENTAL_STRIKE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Talent[] talents() {
|
||||
return new Talent[]{Talent.ELEMENTAL_REACH, Talent.STRIKING_FORCE, Talent.DIRECTED_POWER, Talent.HEROIC_ENERGY};
|
||||
}
|
||||
|
||||
}
|
||||
+4
@@ -28,6 +28,8 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Hex;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicalSleep;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vulnerable;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Weakness;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.duelist.ElementalStrike;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.mage.ElementalBlast;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.mage.WarpBeacon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.DM100;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Eye;
|
||||
@@ -81,6 +83,7 @@ public class AntiMagic extends Armor.Glyph {
|
||||
RESISTS.add( ScrollOfPsionicBlast.class );
|
||||
RESISTS.add( ScrollOfTeleportation.class );
|
||||
|
||||
RESISTS.add( ElementalBlast.class );
|
||||
RESISTS.add( CursedWand.class );
|
||||
RESISTS.add( WandOfBlastWave.class );
|
||||
RESISTS.add( WandOfDisintegration.class );
|
||||
@@ -93,6 +96,7 @@ public class AntiMagic extends Armor.Glyph {
|
||||
RESISTS.add( WandOfTransfusion.class );
|
||||
RESISTS.add( WandOfWarding.Ward.class );
|
||||
|
||||
RESISTS.add( ElementalStrike.class );
|
||||
RESISTS.add( Blazing.class );
|
||||
RESISTS.add( Shocking.class );
|
||||
RESISTS.add( Grim.class );
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Berserk;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicImmune;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.duelist.ElementalStrike;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.KindOfWeapon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfArcana;
|
||||
@@ -392,6 +393,12 @@ abstract public class Weapon extends KindOfWeapon {
|
||||
|
||||
if (attacker.buff(RunicBlade.RunicSlashTracker.class) != null){
|
||||
multi += 2f;
|
||||
attacker.buff(RunicBlade.RunicSlashTracker.class).detach();
|
||||
}
|
||||
|
||||
if (attacker.buff(ElementalStrike.DirectedPowerTracker.class) != null){
|
||||
multi += attacker.buff(ElementalStrike.DirectedPowerTracker.class).enchBoost;
|
||||
attacker.buff(ElementalStrike.DirectedPowerTracker.class).detach();
|
||||
}
|
||||
|
||||
if (attacker.buff(Talent.SpiritBladesTracker.class) != null
|
||||
|
||||
@@ -62,7 +62,7 @@ public class HeroIcon extends Image {
|
||||
public static final int NATURES_POWER = 26;
|
||||
public static final int SPIRIT_HAWK = 27;
|
||||
public static final int CHALLENGE = 28;
|
||||
public static final int DUELIST_2 = 29;
|
||||
public static final int ELEMENTAL_STRIKE= 29;
|
||||
public static final int DUELIST_3 = 30;
|
||||
public static final int RATMOGRIFY = 33;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user