v2.0.0: implemented talents for the challenge armor ability
This commit is contained in:
@@ -866,9 +866,9 @@ actors.hero.talent.combined_lethality.desc=_+1:_ If the Champion uses two differ
|
|||||||
actors.hero.talent.close_the_gap.title=close the gap
|
actors.hero.talent.close_the_gap.title=close the gap
|
||||||
actors.hero.talent.close_the_gap.desc=_+1:_ The Duelist blinks _up to two tiles_ toward her target when starting a duel.\n\n_+2:_ The Duelist blinks _up to three tiles_ toward her target when starting a duel.\n\n_+3:_ The Duelist blinks _up to four tiles_ toward her target when starting a duel.\n\n_+4:_ The Duelist blinks _up to five tiles_ toward her target when starting a duel.\n\nThis blink can go through enemies and hazards, and is taken into account when determining if an enemy is in range to be challenged.
|
actors.hero.talent.close_the_gap.desc=_+1:_ The Duelist blinks _up to two tiles_ toward her target when starting a duel.\n\n_+2:_ The Duelist blinks _up to three tiles_ toward her target when starting a duel.\n\n_+3:_ The Duelist blinks _up to four tiles_ toward her target when starting a duel.\n\n_+4:_ The Duelist blinks _up to five tiles_ toward her target when starting a duel.\n\nThis blink can go through enemies and hazards, and is taken into account when determining if an enemy is in range to be challenged.
|
||||||
actors.hero.talent.invigorating_victory.title=invigorating victory
|
actors.hero.talent.invigorating_victory.title=invigorating victory
|
||||||
actors.hero.talent.invigorating_victory.desc=_+1:_ If the Duelist defeats her target before the duel ends, she heals for _26% of the damage_ she took during the duel.\n\n_+2:_ If the Duelist defeats her target before the duel ends, she heals for _45% of the damage_ she took during the duel.\n\n_+3:_ If the Duelist defeats her target before the duel ends, she heals for _60% of the damage_ she took during the duel.\n\n_+4:_ If the Duelist defeats her target before the duel ends, she heals for _70% of the damage_ she took during the duel.
|
actors.hero.talent.invigorating_victory.desc=_+1:_ If the Duelist defeats her target before the duel ends, she heals for _30% of the damage_ she took during the duel.\n\n_+2:_ If the Duelist defeats her target before the duel ends, she heals for _50% of the damage_ she took during the duel.\n\n_+3:_ If the Duelist defeats her target before the duel ends, she heals for _65% of the damage_ she took during the duel.\n\n_+4:_ If the Duelist defeats her target before the duel ends, she heals for _75% of the damage_ she took during the duel.
|
||||||
actors.hero.talent.elimination_match.title=elimination match
|
actors.hero.talent.elimination_match.title=elimination match
|
||||||
actors.hero.talent.elimination_match.desc=_+1:_ The Duelist can immediately challenge another enemy after a duel ends at a _20% reduced_ charge cost.\n\n_+2:_ The Duelist can immediately challenge another enemy after a duel ends at a _36% reduced_ charge cost.\n\n_+3:_ The Duelist can immediately challenge another enemy after a duel ends at a _50% reduced_ charge cost.\n\n_+4:_ The Duelist can immediately challenge another enemy after a duel ends at a _60% reduced_ charge cost.
|
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
|
#second armor ability
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Regeneration;
|
|||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.SnipersMark;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.SnipersMark;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.duelist.Challenge;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.NaturesPower;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.NaturesPower;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.warrior.Endure;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.warrior.Endure;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic;
|
||||||
@@ -1361,6 +1362,10 @@ public class Hero extends Char {
|
|||||||
|
|
||||||
if (effectiveDamage <= 0) return;
|
if (effectiveDamage <= 0) return;
|
||||||
|
|
||||||
|
if (buff(Challenge.DuelParticipant.class) != null){
|
||||||
|
buff(Challenge.DuelParticipant.class).addDamage(effectiveDamage);
|
||||||
|
}
|
||||||
|
|
||||||
//flash red when hit for serious damage.
|
//flash red when hit for serious damage.
|
||||||
float percentDMG = effectiveDamage / (float)preHP; //percent of current HP that was taken
|
float percentDMG = effectiveDamage / (float)preHP; //percent of current HP that was taken
|
||||||
float percentHP = 1 - ((HT - postHP) / (float)HT); //percent health after damage was taken
|
float percentHP = 1 - ((HT - postHP) / (float)HT); //percent health after damage was taken
|
||||||
|
|||||||
+91
-4
@@ -33,12 +33,16 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
|||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.items.Dewdrop;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
|
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
|
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.ui.HeroIcon;
|
import com.shatteredpixel.shatteredpixeldungeon.ui.HeroIcon;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||||
import com.watabou.noosa.audio.Sample;
|
import com.watabou.noosa.audio.Sample;
|
||||||
import com.watabou.utils.Bundle;
|
import com.watabou.utils.Bundle;
|
||||||
@@ -65,6 +69,16 @@ public class Challenge extends ArmorAbility {
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float chargeUse( Hero hero ) {
|
||||||
|
float chargeUse = super.chargeUse(hero);
|
||||||
|
if (hero.buff(EliminationMatchTracker.class) != null){
|
||||||
|
//reduced charge use by 20%/36%/50%/60%
|
||||||
|
chargeUse *= Math.pow(0.795, hero.pointsInTalent(Talent.ELIMINATION_MATCH));
|
||||||
|
}
|
||||||
|
return chargeUse;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void activate(ClassArmor armor, Hero hero, Integer target) {
|
protected void activate(ClassArmor armor, Hero hero, Integer target) {
|
||||||
if (target == null || !Dungeon.level.heroFOV[target]){
|
if (target == null || !Dungeon.level.heroFOV[target]){
|
||||||
@@ -89,18 +103,55 @@ public class Challenge extends ArmorAbility {
|
|||||||
for (Char c : Actor.chars()) {
|
for (Char c : Actor.chars()) {
|
||||||
if (c != hero) passable[c.pos] = false;
|
if (c != hero) passable[c.pos] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PathFinder.buildDistanceMap(targetCh.pos, passable);
|
PathFinder.buildDistanceMap(targetCh.pos, passable);
|
||||||
if (PathFinder.distance[hero.pos] == Integer.MAX_VALUE){
|
int[] reachable = PathFinder.distance.clone();
|
||||||
|
|
||||||
|
int blinkpos = hero.pos;
|
||||||
|
if (hero.hasTalent(Talent.CLOSE_THE_GAP)){
|
||||||
|
|
||||||
|
int blinkrange = 1 + hero.pointsInTalent(Talent.CLOSE_THE_GAP);
|
||||||
|
PathFinder.buildDistanceMap(hero.pos, BArray.not(Dungeon.level.solid,null), blinkrange);
|
||||||
|
|
||||||
|
for (int i = 0; i < PathFinder.distance.length; i++){
|
||||||
|
if (PathFinder.distance[i] == Integer.MAX_VALUE
|
||||||
|
|| reachable[i] == Integer.MAX_VALUE
|
||||||
|
|| i == targetCh.pos){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Dungeon.level.distance(i, targetCh.pos) < Dungeon.level.distance(blinkpos, targetCh.pos)){
|
||||||
|
blinkpos = i;
|
||||||
|
} else if (Dungeon.level.distance(i, targetCh.pos) == Dungeon.level.distance(blinkpos, targetCh.pos)){
|
||||||
|
if (Dungeon.level.trueDistance(i, hero.pos) < Dungeon.level.trueDistance(blinkpos, hero.pos)){
|
||||||
|
blinkpos = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PathFinder.distance[blinkpos] == Integer.MAX_VALUE){
|
||||||
GLog.w(Messages.get(this, "unreachable_target"));
|
GLog.w(Messages.get(this, "unreachable_target"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Dungeon.level.distance(hero.pos, targetCh.pos) >= 5){
|
if (Dungeon.level.distance(blinkpos, targetCh.pos) >= 5){
|
||||||
GLog.w(Messages.get(this, "distant_target"));
|
GLog.w(Messages.get(this, "distant_target"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (blinkpos != hero.pos){
|
||||||
|
Dungeon.hero.pos = blinkpos;
|
||||||
|
Dungeon.level.occupyCell(Dungeon.hero);
|
||||||
|
//prevents the hero from being interrupted by seeing new enemies
|
||||||
|
Dungeon.observe();
|
||||||
|
GameScene.updateFog();
|
||||||
|
Dungeon.hero.checkVisibleMobs();
|
||||||
|
|
||||||
|
Dungeon.hero.sprite.place( Dungeon.hero.pos );
|
||||||
|
CellEmitter.get( Dungeon.hero.pos ).burst( Speck.factory( Speck.WOOL ), 6 );
|
||||||
|
Sample.INSTANCE.play( Assets.Sounds.PUFF );
|
||||||
|
}
|
||||||
|
|
||||||
boolean bossTarget = Char.hasProp(targetCh, Char.Property.BOSS);
|
boolean bossTarget = Char.hasProp(targetCh, Char.Property.BOSS);
|
||||||
for (Char toFreeze : Actor.chars()){
|
for (Char toFreeze : Actor.chars()){
|
||||||
if (toFreeze != targetCh && toFreeze.alignment != hero.alignment
|
if (toFreeze != targetCh && toFreeze.alignment != hero.alignment
|
||||||
@@ -124,6 +175,10 @@ public class Challenge extends ArmorAbility {
|
|||||||
hero.sprite.zap(target);
|
hero.sprite.zap(target);
|
||||||
|
|
||||||
hero.next();
|
hero.next();
|
||||||
|
|
||||||
|
if (hero.buff(EliminationMatchTracker.class) != null){
|
||||||
|
hero.buff(EliminationMatchTracker.class).detach();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,11 +187,14 @@ public class Challenge extends ArmorAbility {
|
|||||||
return new Talent[]{Talent.CLOSE_THE_GAP, Talent.INVIGORATING_VICTORY, Talent.ELIMINATION_MATCH, Talent.HEROIC_ENERGY};
|
return new Talent[]{Talent.CLOSE_THE_GAP, Talent.INVIGORATING_VICTORY, Talent.ELIMINATION_MATCH, Talent.HEROIC_ENERGY};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class EliminationMatchTracker extends FlavourBuff{};
|
||||||
|
|
||||||
public static class DuelParticipant extends Buff {
|
public static class DuelParticipant extends Buff {
|
||||||
|
|
||||||
public static float DURATION = 10f;
|
public static float DURATION = 10f;
|
||||||
|
|
||||||
private int left = (int)DURATION;
|
private int left = (int)DURATION;
|
||||||
|
private int takenDmg = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int icon() {
|
public int icon() {
|
||||||
@@ -153,6 +211,10 @@ public class Challenge extends ArmorAbility {
|
|||||||
return Integer.toString(left);
|
return Integer.toString(left);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addDamage(int dmg){
|
||||||
|
takenDmg += dmg;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean act() {
|
public boolean act() {
|
||||||
|
|
||||||
@@ -185,6 +247,24 @@ public class Challenge extends ArmorAbility {
|
|||||||
if (target.alignment != Dungeon.hero.alignment){
|
if (target.alignment != Dungeon.hero.alignment){
|
||||||
Sample.INSTANCE.play(Assets.Sounds.BOSS);
|
Sample.INSTANCE.play(Assets.Sounds.BOSS);
|
||||||
GameScene.flash(0x80FFFFFF);
|
GameScene.flash(0x80FFFFFF);
|
||||||
|
|
||||||
|
if (Dungeon.hero.hasTalent(Talent.INVIGORATING_VICTORY)){
|
||||||
|
DuelParticipant heroBuff = Dungeon.hero.buff(DuelParticipant.class);
|
||||||
|
|
||||||
|
int hpToHeal = 0;
|
||||||
|
if (heroBuff != null){
|
||||||
|
hpToHeal = heroBuff.takenDmg;
|
||||||
|
}
|
||||||
|
|
||||||
|
//heals for 30%/50%/65%/75% of taken damage, based on talent points
|
||||||
|
hpToHeal = (int)Math.round(hpToHeal * (1f - Math.pow(0.707f, Dungeon.hero.pointsInTalent(Talent.INVIGORATING_VICTORY))));
|
||||||
|
hpToHeal = Math.min(hpToHeal, Dungeon.hero.HT - Dungeon.hero.HP);
|
||||||
|
if (hpToHeal > 0){
|
||||||
|
Dungeon.hero.HP += hpToHeal;
|
||||||
|
Dungeon.hero.sprite.emitter().start( Speck.factory( Speck.HEALING ), 0.33f, 6 );
|
||||||
|
Dungeon.hero.sprite.showStatus( CharSprite.POSITIVE, Messages.get(Dewdrop.class, "heal", hpToHeal) );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Char ch : Actor.chars()) {
|
for (Char ch : Actor.chars()) {
|
||||||
@@ -195,9 +275,13 @@ public class Challenge extends ArmorAbility {
|
|||||||
ch.buff(DuelParticipant.class).detach();
|
ch.buff(DuelParticipant.class).detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (target == Dungeon.hero){
|
} else if (target != Dungeon.hero){
|
||||||
GameScene.flash(0x80FFFFFF);
|
GameScene.flash(0x80FFFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (target == Dungeon.hero && Dungeon.hero.hasTalent(Talent.ELIMINATION_MATCH) && target.isAlive()){
|
||||||
|
Buff.affect(target, EliminationMatchTracker.class, 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -206,17 +290,20 @@ public class Challenge extends ArmorAbility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final String LEFT = "left";
|
private static final String LEFT = "left";
|
||||||
|
private static final String TAKEN_DMG = "taken_dmg";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void storeInBundle(Bundle bundle) {
|
public void storeInBundle(Bundle bundle) {
|
||||||
super.storeInBundle(bundle);
|
super.storeInBundle(bundle);
|
||||||
bundle.put(LEFT, left);
|
bundle.put(LEFT, left);
|
||||||
|
bundle.put(TAKEN_DMG, takenDmg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void restoreFromBundle(Bundle bundle) {
|
public void restoreFromBundle(Bundle bundle) {
|
||||||
super.restoreFromBundle(bundle);
|
super.restoreFromBundle(bundle);
|
||||||
left = bundle.getInt(LEFT);
|
left = bundle.getInt(LEFT);
|
||||||
|
takenDmg = bundle.getInt(TAKEN_DMG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user