v2.0.0: implemented talents for the challenge armor ability

This commit is contained in:
Evan Debenham
2023-01-19 17:02:12 -05:00
parent 4cb787a4bf
commit dc1f6b2a16
3 changed files with 98 additions and 6 deletions

View File

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

View File

@@ -60,6 +60,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Regeneration;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.SnipersMark;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vertigo;
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.warrior.Endure;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mimic;
@@ -1361,6 +1362,10 @@ public class Hero extends Char {
if (effectiveDamage <= 0) return;
if (buff(Challenge.DuelParticipant.class) != null){
buff(Challenge.DuelParticipant.class).addDamage(effectiveDamage);
}
//flash red when hit for serious damage.
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

View File

@@ -33,12 +33,16 @@ 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.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.items.Dewdrop;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.HeroIcon;
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Bundle;
@@ -65,6 +69,16 @@ public class Challenge extends ArmorAbility {
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
protected void activate(ClassArmor armor, Hero hero, Integer target) {
if (target == null || !Dungeon.level.heroFOV[target]){
@@ -89,18 +103,55 @@ public class Challenge extends ArmorAbility {
for (Char c : Actor.chars()) {
if (c != hero) passable[c.pos] = false;
}
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"));
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"));
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);
for (Char toFreeze : Actor.chars()){
if (toFreeze != targetCh && toFreeze.alignment != hero.alignment
@@ -124,6 +175,10 @@ public class Challenge extends ArmorAbility {
hero.sprite.zap(target);
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};
}
public static class EliminationMatchTracker extends FlavourBuff{};
public static class DuelParticipant extends Buff {
public static float DURATION = 10f;
private int left = (int)DURATION;
private int takenDmg = 0;
@Override
public int icon() {
@@ -153,6 +211,10 @@ public class Challenge extends ArmorAbility {
return Integer.toString(left);
}
public void addDamage(int dmg){
takenDmg += dmg;
}
@Override
public boolean act() {
@@ -185,6 +247,24 @@ public class Challenge extends ArmorAbility {
if (target.alignment != Dungeon.hero.alignment){
Sample.INSTANCE.play(Assets.Sounds.BOSS);
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()) {
@@ -195,9 +275,13 @@ public class Challenge extends ArmorAbility {
ch.buff(DuelParticipant.class).detach();
}
}
} else if (target == Dungeon.hero){
} else if (target != Dungeon.hero){
GameScene.flash(0x80FFFFFF);
}
if (target == Dungeon.hero && Dungeon.hero.hasTalent(Talent.ELIMINATION_MATCH) && target.isAlive()){
Buff.affect(target, EliminationMatchTracker.class, 3);
}
}
@Override
@@ -206,17 +290,20 @@ public class Challenge extends ArmorAbility {
}
private static final String LEFT = "left";
private static final String TAKEN_DMG = "taken_dmg";
@Override
public void storeInBundle(Bundle bundle) {
super.storeInBundle(bundle);
bundle.put(LEFT, left);
bundle.put(TAKEN_DMG, takenDmg);
}
@Override
public void restoreFromBundle(Bundle bundle) {
super.restoreFromBundle(bundle);
left = bundle.getInt(LEFT);
takenDmg = bundle.getInt(TAKEN_DMG);
}
}