v2.0.0: added lethal haste, added icon for barrier metamorph, improved lethal momentum icon

This commit is contained in:
Evan Debenham
2022-12-16 18:00:21 -05:00
parent 04b2619ff9
commit 5a1b8fc710
16 changed files with 81 additions and 10 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@@ -542,6 +542,10 @@ actors.hero.talent$rejuvenatingstepscooldown.name=rejuvenating steps cooldown
actors.hero.talent$rejuvenatingstepscooldown.desc=You have recently used this talent, and must wait before using it again.\n\nTurns remaining: %s.
actors.hero.talent$seershotcooldown.name=seer shot cooldown
actors.hero.talent$seershotcooldown.desc=You have recently used this talent, and must wait before using it again.\n\nTurns remaining: %s.
actors.hero.talent$aggressivebarriercooldown.name=aggressive barrier cooldown
actors.hero.talent$aggressivebarriercooldown.desc=You have recently used this talent, and must wait before using it again.\n\nTurns remaining: %s.
actors.hero.talent$lethalhastecooldown.name=lethal haste cooldown
actors.hero.talent$lethalhastecooldown.desc=You have recently used this talent, and must wait before using it again.\n\nTurns remaining: %s.
actors.hero.talent$swiftequipcooldown.name=swift equip cooldown
actors.hero.talent$swiftequipcooldown.desc=You have recently used this talent, and must wait before using it again.\n\nTurns remaining: %s.
@@ -805,7 +809,7 @@ actors.hero.talent.adventurers_intuition.desc=_+1:_ The Duelist identifies weapo
actors.hero.talent.aggressive_barrier.title=aggressive barrier
actors.hero.talent.aggressive_barrier.desc=_+1:_ The Duelist gain 2 shielding when she uses a weapon ability and is below _33% health_.\n\n_+2:_ The Duelist gain 2 shielding when she uses a weapon ability and is below _50% health_.
actors.hero.talent.aggressive_barrier.meta_desc=_If this talent is gained by a different hero_ it will instead grant shielding when making a melee attack at low health, with a 30 turn cooldown.
actors.hero.talent.aggressive_barrier.meta_desc=_If this talent is gained by a different hero_ it will instead grant shielding when making a melee attack at low health, with a 50 turn cooldown.
actors.hero.talent.focused_meal.title=focused meal
actors.hero.talent.focused_meal.desc=_+1:_ Eating food takes the Duelist 1 turn and grants her _1 weapon charge_.\n\n_+2:_ Eating food takes the Duelist 1 turn and grants her _1.5 weapon charge_.
@@ -815,7 +819,9 @@ actors.hero.talent.restored_agility.desc=_+1:_ The Duelist has _2x evasion_ whil
actors.hero.talent.weapon_recharging.title=weapon recharging
actors.hero.talent.weapon_recharging.desc=_+1:_ The Duelist gains one weapon charge every _15 turns_ when under the effect of wand or artifact recharging buffs.\n\n_+2:_ The Duelist gains one weapon charge every _10 turns_ when under the effect of wand or artifact recharging buffs.
actors.hero.talent.weapon_recharging.meta_desc=_If this talent is gained by a different hero_ it will instead cause them to deal +5% melee damage while recharging at +1, or +7.5% melee damage while recharging at +2.
actors.hero.talent.lethal_haste.title=lethal haste
actors.hero.talent.lethal_haste.desc=_+1:_ When the Duelist lands a killing blow with a weapon ability, she gains _1 turn_ of haste.\n\n_+2:_ When the Duelist lands a killing blow with a weapon ability, she gains _2 turns_ of haste.
actors.hero.talent.lethal_haste.meta_desc=_If this talent is gained by a different hero_ it will instead trigger with regular weapon attacks, with a 100 turn cooldown.
actors.hero.talent.swift_equip.title=swift equip
actors.hero.talent.swift_equip.desc=_+1:_ The Duelist can switch her equipped weapon instantly _one time_, with a 50 turn cooldown.\n\n_+2:_ The Duelist can switch her equipped weapon instantly _twice within 5 turns_, with a 50 turn cooldown.\n\nIf the Duelist has this talent and it is not on cooldown, quick-using an unequipped weapon will equip it.

View File

@@ -1195,7 +1195,7 @@ public class Hero extends Char {
&& buff(Talent.AggressiveBarrierCooldown.class) == null
&& (HP / (float)HT) < 0.167f*(1+pointsInTalent(Talent.AGGRESSIVE_BARRIER))){
Buff.affect(this, Barrier.class).setShield(2);
Buff.affect(this, Talent.AggressiveBarrierCooldown.class, 30f);
Buff.affect(this, Talent.AggressiveBarrierCooldown.class, 50f);
}
sprite.attack( enemy.pos );

View File

@@ -150,7 +150,7 @@ public enum Talent {
//Duelist T1
STRENGTHENING_MEAL(128), ADVENTURERS_INTUITION(129), DUELIST_T1_3(130), AGGRESSIVE_BARRIER(131),
//Duelist T2
FOCUSED_MEAL(132), RESTORED_AGILITY(133), WEAPON_RECHARGING(134), DUELIST_T2_4(135), SWIFT_EQUIP(136),
FOCUSED_MEAL(132), RESTORED_AGILITY(133), WEAPON_RECHARGING(134), LETHAL_HASTE(135), SWIFT_EQUIP(136),
//Duelist T3
LIGHTWEIGHT_CHARGE(137, 3), DEADLY_FOLLOWUP(138, 3),
//Duelist S1 T3
@@ -228,8 +228,17 @@ public enum Talent {
public float iconFadePercent() { return Math.max(0, visualcooldown() / 20); }
};
public static class SpiritBladesTracker extends FlavourBuff{};
public static class AggressiveBarrierCooldown extends FlavourBuff{};
public static class AggressiveBarrierCooldown extends FlavourBuff{
public int icon() { return BuffIndicator.TIME; }
public void tintIcon(Image icon) { icon.hardlight(0.35f, 0f, 0.7f); }
public float iconFadePercent() { return Math.max(0, visualcooldown() / 50); }
};;
public static class RestoredAgilityTracker extends FlavourBuff{};
public static class LethalHasteCooldown extends FlavourBuff{
public int icon() { return BuffIndicator.TIME; }
public void tintIcon(Image icon) { icon.hardlight(0.35f, 0f, 0.7f); }
public float iconFadePercent() { return Math.max(0, visualcooldown() / 100); }
};
public static class SwiftEquipCooldown extends FlavourBuff{
public boolean secondUse;
public boolean hasSecondUse(){
@@ -679,7 +688,7 @@ public enum Talent {
Collections.addAll(tierTalents, INVIGORATING_MEAL, RESTORED_NATURE, REJUVENATING_STEPS, HEIGHTENED_SENSES, DURABLE_PROJECTILES);
break;
case DUELIST:
Collections.addAll(tierTalents, FOCUSED_MEAL, RESTORED_AGILITY, WEAPON_RECHARGING, DUELIST_T2_4, SWIFT_EQUIP);
Collections.addAll(tierTalents, FOCUSED_MEAL, RESTORED_AGILITY, WEAPON_RECHARGING, LETHAL_HASTE, SWIFT_EQUIP);
break;
}
for (Talent talent : tierTalents){

View File

@@ -37,6 +37,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ChampionEnemy;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Charm;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Corruption;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Dread;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Haste;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Hunger;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MindVision;
@@ -45,6 +46,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Sleep;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.SoulMark;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Terror;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.DirectableAlly;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
@@ -64,6 +66,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.SpiritBow;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Lucky;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MeleeWeapon;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.darts.Dart;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
@@ -746,11 +749,19 @@ public abstract class Mob extends Char {
if (alignment == Alignment.ENEMY){
rollToDropLoot();
if ((cause == Dungeon.hero || cause instanceof Weapon || cause instanceof Weapon.Enchantment)
&& Dungeon.hero.hasTalent(Talent.LETHAL_MOMENTUM)
&& Random.Float() < 0.34f + 0.33f* Dungeon.hero.pointsInTalent(Talent.LETHAL_MOMENTUM)){
Buff.affect(Dungeon.hero, Talent.LethalMomentumTracker.class, 0f);
if (cause == Dungeon.hero || cause instanceof Weapon || cause instanceof Weapon.Enchantment){
if (Dungeon.hero.hasTalent(Talent.LETHAL_MOMENTUM)
&& Random.Float() < 0.34f + 0.33f* Dungeon.hero.pointsInTalent(Talent.LETHAL_MOMENTUM)){
Buff.affect(Dungeon.hero, Talent.LethalMomentumTracker.class, 0f);
}
if (Dungeon.hero.heroClass != HeroClass.DUELIST
&& Dungeon.hero.hasTalent(Talent.LETHAL_HASTE)
&& Dungeon.hero.buff(Talent.LethalHasteCooldown.class) == null){
Buff.affect(Dungeon.hero, Talent.LethalHasteCooldown.class, 100f);
Buff.affect(Dungeon.hero, Haste.class, 0.67f + Dungeon.hero.pointsInTalent(Talent.LETHAL_HASTE));
}
}
}
if (Dungeon.hero.isAlive() && !Dungeon.level.heroFOV[pos]) {

View File

@@ -205,6 +205,8 @@ public class Pickaxe extends MeleeWeapon {
if (hero.attack(enemy, damageMulti, 0, Char.INFINITE_ACCURACY)) {
if (enemy.isAlive()) {
Buff.affect(enemy, Vulnerable.class, 3f);
} else {
onAbilityKill(hero);
}
Sample.INSTANCE.play(Assets.Sounds.HIT_STRONG);
}

View File

@@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee;
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.FlavourBuff;
@@ -67,6 +68,18 @@ public class Flail extends MeleeWeapon {
public float accuracyFactor(Char owner, Char target) {
SpinAbilityTracker spin = owner.buff(SpinAbilityTracker.class);
if (spin != null) {
//have to handle this in an actor tied to the regular attack =S
Actor.add(new Actor() {
{ actPriority = VFX_PRIO; }
@Override
protected boolean act() {
if (owner instanceof Hero && !target.isAlive()){
onAbilityKill((Hero)owner);
}
Actor.remove(this);
return true;
}
});
//we detach and calculate bonus here in case the attack misses
spin.detach();
spinBonus = 1f + 0.2f*spin.spins;

View File

@@ -81,6 +81,9 @@ public class Greataxe extends MeleeWeapon {
onAbilityUsed(hero);
if (hero.attack(enemy, 1.5f, 0, Char.INFINITE_ACCURACY)){
Sample.INSTANCE.play(Assets.Sounds.HIT_STRONG);
if (!enemy.isAlive()){
onAbilityKill(hero);
}
}
hero.spendAndNext(2*hero.attackDelay());
}

View File

@@ -85,6 +85,8 @@ public class Mace extends MeleeWeapon {
Sample.INSTANCE.play(Assets.Sounds.HIT_STRONG);
if (enemy.isAlive()){
Buff.affect(enemy, Vulnerable.class, 5f);
} else {
wep.onAbilityKill(hero);
}
}
hero.spendAndNext(hero.attackDelay());

View File

@@ -26,6 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ArtifactRecharge;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Barrier;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Haste;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LockedFloor;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Recharging;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
@@ -93,9 +94,11 @@ public class MeleeWeapon extends Weapon {
GLog.i(Messages.get(this, "swift_equip"));
} else {
GLog.w(Messages.get(this, "ability_need_equip"));
usesTargeting = false;
}
} else {
GLog.w(Messages.get(this, "ability_need_equip"));
usesTargeting = false;
}
} else if ((Buff.affect(hero, Charger.class).charges + Buff.affect(hero, Charger.class).partialCharge)
< abilityChargeUse(hero)) {
@@ -161,6 +164,13 @@ public class MeleeWeapon extends Weapon {
updateQuickslot();
}
protected void onAbilityKill( Hero hero ){
if (hero.hasTalent(Talent.LETHAL_HASTE)){
//effectively 1/2 turns of haste
Buff.prolong(hero, Haste.class, 0.67f+hero.pointsInTalent(Talent.LETHAL_HASTE));
}
}
public float abilityChargeUse( Hero hero ){
float chargeUse = 1f;
if (hero.hasTalent(Talent.LIGHTWEIGHT_CHARGE) && tier <= 3){

View File

@@ -112,6 +112,9 @@ public class Rapier extends MeleeWeapon {
onAbilityUsed(hero);
if (hero.attack(enemy, 1f, augment.damageFactor(3 + level()), Char.INFINITE_ACCURACY)){
Sample.INSTANCE.play(Assets.Sounds.HIT_STRONG);
if (!enemy.isAlive()){
onAbilityKill(hero);
}
}
hero.spendAndNext(hero.attackDelay());
}

View File

@@ -84,6 +84,9 @@ public class RunicBlade extends MeleeWeapon {
onAbilityUsed(hero);
if (hero.attack(enemy, 1f, 0, Char.INFINITE_ACCURACY)){
Sample.INSTANCE.play(Assets.Sounds.HIT_STRONG);
if (!enemy.isAlive()){
onAbilityKill(hero);
}
}
tracker.detach();
hero.spendAndNext(hero.attackDelay());

View File

@@ -84,6 +84,9 @@ public class Sai extends MeleeWeapon {
public void call() {
wep.onAbilityUsed(hero);
boolean hit = hero.attack(enemy, 1, 0, Char.INFINITE_ACCURACY);
if (hit && !enemy.isAlive()){
wep.onAbilityKill(hero);
}
HashSet<ComboStrikeTracker> buffs = hero.buffs(ComboStrikeTracker.class);
int recentHits = 0;

View File

@@ -90,6 +90,8 @@ public class Spear extends MeleeWeapon {
trajectory = new Ballistica(trajectory.collisionPos, trajectory.path.get(trajectory.path.size() - 1), Ballistica.PROJECTILE);
//knock them back along that ballistica
WandOfBlastWave.throwChar(enemy, trajectory, 1, true, false, hero.getClass());
} else {
wep.onAbilityKill(hero);
}
Sample.INSTANCE.play(Assets.Sounds.HIT_STRONG);
}

View File

@@ -89,6 +89,7 @@ public class Sword extends MeleeWeapon {
}
if (!enemy.isAlive()){
wep.onAbilityKill(hero);
hero.next();
Buff.prolong(hero, CleaveTracker.class, 4f); //1 less as attack was instant
} else {

View File

@@ -76,6 +76,9 @@ public class Whip extends MeleeWeapon {
onAbilityUsed(hero);
for (Char ch : targets) {
hero.attack(ch);
if (!ch.isAlive()){
onAbilityKill(hero);
}
}
hero.spendAndNext(hero.attackDelay());
}