diff --git a/core/src/main/assets/messages/actors/actors.properties b/core/src/main/assets/messages/actors/actors.properties index fd7e4e396..72c78a1de 100644 --- a/core/src/main/assets/messages/actors/actors.properties +++ b/core/src/main/assets/messages/actors/actors.properties @@ -542,6 +542,8 @@ 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$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. #warrior actors.hero.talent.hearty_meal.title=hearty meal @@ -815,7 +817,7 @@ actors.hero.talent.weapon_recharging.desc=_+1:_ The Duelist gains one weapon cha 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, and +7.5% melee damage while recharging at +2. 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 30 turn cooldown.\n\n_+2:_ The Duelist can switch her equipped weapon instantly _twice within 5 turns_, with a 30 turn cooldown.\n\nIf the Duelist has this talent and it is not on cooldown, quick-using an unequipped weapon will equip it. +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. #universal actors.hero.talent.heroic_energy.title=heroic energy diff --git a/core/src/main/assets/messages/items/items.properties b/core/src/main/assets/messages/items/items.properties index 3658ae9d7..c371a76a5 100644 --- a/core/src/main/assets/messages/items/items.properties +++ b/core/src/main/assets/messages/items/items.properties @@ -1599,6 +1599,7 @@ items.weapon.melee.meleeweapon.stats_known=This _tier-%1$d_ melee weapon deals _ items.weapon.melee.meleeweapon.stats_unknown=Typically this _tier-%1$d_ melee weapon deals _%2$d-%3$d damage_ and requires _%4$d strength_ to use properly. items.weapon.melee.meleeweapon.probably_too_heavy=Probably this weapon is too heavy for you. items.weapon.melee.meleeweapon.stats_desc= +items.weapon.melee.meleeweapon.swift_equip=You quickly switch your equipped weapon. items.weapon.melee.meleeweapon.ability_need_equip=You must equip that weapon to use its ability. items.weapon.melee.meleeweapon.ability_no_charge=You don't have enough energy to use that ability. items.weapon.melee.meleeweapon.ability_no_target=There is no target there. diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Talent.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Talent.java index 3c9987ab2..fb544c1fc 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Talent.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Talent.java @@ -149,7 +149,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), DUELIST_T2_5(136), + FOCUSED_MEAL(132), RESTORED_AGILITY(133), WEAPON_RECHARGING(134), DUELIST_T2_4(135), SWIFT_EQUIP(136), //Duelist T3 DUELIST_T3_1(137, 3), DUELIST_T3_2(138, 3), //Duelist S1 T3 @@ -229,6 +229,31 @@ public enum Talent { public static class SpiritBladesTracker extends FlavourBuff{}; public static class AggressiveBarrierCooldown extends FlavourBuff{}; public static class RestoredAgilityTracker extends FlavourBuff{}; + public static class SwiftEquipCooldown extends FlavourBuff{ + public boolean secondUse; + public boolean hasSecondUse(){ + return secondUse && cooldown() > 44f; + } + + public int icon() { return BuffIndicator.TIME; } + public void tintIcon(Image icon) { + if (hasSecondUse()) icon.hardlight(0.85f, 0f, 1.0f); + else icon.hardlight(0.35f, 0f, 0.7f); + } + public float iconFadePercent() { return GameMath.gate(0, visualcooldown() / 50f, 1); } + + private static final String SECOND_USE = "second_use"; + @Override + public void storeInBundle(Bundle bundle) { + super.storeInBundle(bundle); + bundle.put(SECOND_USE, secondUse); + } + @Override + public void restoreFromBundle(Bundle bundle) { + super.restoreFromBundle(bundle); + secondUse = bundle.getBoolean(SECOND_USE); + } + }; int icon; int maxPoints; @@ -634,7 +659,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, DUELIST_T2_5); + Collections.addAll(tierTalents, FOCUSED_MEAL, RESTORED_AGILITY, WEAPON_RECHARGING, DUELIST_T2_4, SWIFT_EQUIP); break; } for (Talent talent : tierTalents){ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/KindOfWeapon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/KindOfWeapon.java index 2c1d033ac..b76dd0e8b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/KindOfWeapon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/KindOfWeapon.java @@ -26,6 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.Badges; 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.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; @@ -67,8 +68,21 @@ abstract public class KindOfWeapon extends EquipableItem { equipCursed( hero ); GLog.n( Messages.get(KindOfWeapon.class, "equip_cursed") ); } - - hero.spendAndNext( TIME_TO_EQUIP ); + + if (hero.hasTalent(Talent.SWIFT_EQUIP)) { + if (hero.buff(Talent.SwiftEquipCooldown.class) == null){ + hero.spendAndNext(-hero.cooldown()); + Buff.affect(hero, Talent.SwiftEquipCooldown.class, 49f) + .secondUse = hero.pointsInTalent(Talent.SWIFT_EQUIP) == 2; + } else if (hero.buff(Talent.SwiftEquipCooldown.class).hasSecondUse()) { + hero.spendAndNext(-hero.cooldown()); + hero.buff(Talent.SwiftEquipCooldown.class).secondUse = false; + } else { + hero.spendAndNext(TIME_TO_EQUIP); + } + } else { + hero.spendAndNext(TIME_TO_EQUIP); + } return true; } else { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/MeleeWeapon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/MeleeWeapon.java index 80ef5ae06..e3746eb35 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/MeleeWeapon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/melee/MeleeWeapon.java @@ -86,7 +86,17 @@ public class MeleeWeapon extends Weapon { if (action.equals(AC_ABILITY)){ if (!isEquipped(hero)) { - GLog.w(Messages.get(this, "ability_need_equip")); + if (hero.hasTalent(Talent.SWIFT_EQUIP)){ + if (hero.buff(Talent.SwiftEquipCooldown.class) == null + || hero.buff(Talent.SwiftEquipCooldown.class).hasSecondUse()){ + execute(hero, AC_EQUIP); + GLog.i(Messages.get(this, "swift_equip")); + } else { + GLog.w(Messages.get(this, "ability_need_equip")); + } + } else { + GLog.w(Messages.get(this, "ability_need_equip")); + } } else if (Buff.affect(hero, Charger.class).charges < abilityChargeUse()) { GLog.w(Messages.get(this, "ability_no_charge")); usesTargeting = false;