From 5d33849278459f17f875fc378ece2f17a37aaa9b Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Tue, 28 Feb 2023 12:55:49 -0500 Subject: [PATCH] v2.0.0: implemented the monastic vigor talent --- .../shatteredpixeldungeon/actors/Char.java | 4 ++ .../actors/buffs/MonkEnergy.java | 70 +++++++++++++++++-- .../actors/hero/Belongings.java | 1 - .../actors/hero/Hero.java | 16 +++-- .../items/rings/RingOfForce.java | 20 +++++- .../items/weapon/Weapon.java | 6 +- 6 files changed, 102 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java index ab6799d8f..7659ae85f 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java @@ -389,6 +389,10 @@ public abstract class Char extends Actor { dmg *= 0.67f; } + if (enemy.buff(MonkEnergy.MonkAbility.Meditate.MeditateResistance.class) != null){ + dmg *= 0.2f; + } + if ( buff(Weakness.class) != null ){ dmg *= 0.67f; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/MonkEnergy.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/MonkEnergy.java index 7eaecbd86..d1aaa44e7 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/MonkEnergy.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/MonkEnergy.java @@ -206,6 +206,11 @@ public class MonkEnergy extends Buff implements ActionIndicator.Action { } } + public boolean abilitiesEmpowered( Hero hero ){ + //100%/85%/70% energy at +1/+2/+3 + return energy/energyCap() >= 1.15f - 0.15f*hero.pointsInTalent(Talent.MONASTIC_VIGOR); + } + @Override public String actionName() { return Messages.get(this, "action"); @@ -251,6 +256,8 @@ public class MonkEnergy extends Buff implements ActionIndicator.Action { public static class UnarmedAbilityTracker extends FlavourBuff{}; public static class JustHitTracker extends FlavourBuff{}; + public static class FlurryEmpowerTracker extends FlavourBuff{}; + public static class Flurry extends MonkAbility { @Override @@ -260,7 +267,8 @@ public class MonkEnergy extends Buff implements ActionIndicator.Action { @Override public int cooldown() { - return Dungeon.hero.buff(JustHitTracker.class) != null ? 0 : 6; + //1 less turn as no time is spent flurrying + return Dungeon.hero.buff(JustHitTracker.class) != null ? 0 : 5; } @Override @@ -293,6 +301,10 @@ public class MonkEnergy extends Buff implements ActionIndicator.Action { return; } + if (Buff.affect(hero, MonkEnergy.class).abilitiesEmpowered(hero)){ + Buff.affect(hero, FlurryEmpowerTracker.class, 0f); + } + hero.sprite.attack(enemy.pos, new Callback() { @Override public void call() { @@ -311,6 +323,9 @@ public class MonkEnergy extends Buff implements ActionIndicator.Action { if (hero.buff(JustHitTracker.class) != null) { hero.buff(JustHitTracker.class).detach(); } + if (hero.buff(FlurryEmpowerTracker.class) != null){ + hero.buff(FlurryEmpowerTracker.class).detach(); + } } }); } else { @@ -321,6 +336,9 @@ public class MonkEnergy extends Buff implements ActionIndicator.Action { if (hero.buff(JustHitTracker.class) != null) { hero.buff(JustHitTracker.class).detach(); } + if (hero.buff(FlurryEmpowerTracker.class) != null){ + hero.buff(FlurryEmpowerTracker.class).detach(); + } } } }); @@ -336,15 +354,20 @@ public class MonkEnergy extends Buff implements ActionIndicator.Action { @Override public int cooldown() { - return 6; + //1 less if focus was instant + return Buff.affect(Dungeon.hero, MonkEnergy.class).abilitiesEmpowered(Dungeon.hero) ? 5 : 6; } @Override public void doAbility(Hero hero, Integer target) { Buff.prolong(hero, FocusBuff.class, 30f); + if (Buff.affect(hero, MonkEnergy.class).abilitiesEmpowered(hero)){ + hero.next(); + } else { + hero.spendAndNext(1f); + } Buff.affect(hero, MonkEnergy.class).abilityUsed(this); - hero.spendAndNext(1f); } public static class FocusBuff extends FlavourBuff { @@ -395,7 +418,12 @@ public class MonkEnergy extends Buff implements ActionIndicator.Action { return; } - if (Dungeon.level.distance(hero.pos, target) > 3){ + int range = 3; + if (Buff.affect(hero, MonkEnergy.class).abilitiesEmpowered(hero)){ + range += 2; + } + + if (Dungeon.level.distance(hero.pos, target) > range){ GLog.w(Messages.get(MeleeWeapon.class, "ability_no_target")); return; } @@ -474,12 +502,13 @@ public class MonkEnergy extends Buff implements ActionIndicator.Action { @Override public void call() { AttackIndicator.target(enemy); - if (hero.attack(enemy, 4f, 0, Char.INFINITE_ACCURACY)){ + boolean empowered = Buff.affect(hero, MonkEnergy.class).abilitiesEmpowered(hero); + + if (hero.attack(enemy, empowered ? 4f : 3f, 0, Char.INFINITE_ACCURACY)){ Sample.INSTANCE.play(Assets.Sounds.HIT_STRONG); } if (enemy.isAlive()){ - int oldPos = enemy.pos; //trace a ballistica to our target (which will also extend past them Ballistica trajectory = new Ballistica(hero.pos, enemy.pos, Ballistica.STOP_TARGET); //trim it to just be the part that goes past them @@ -495,6 +524,25 @@ public class MonkEnergy extends Buff implements ActionIndicator.Action { hero.spendAndNext(hero.attackDelay()); tracker.detach(); Buff.affect(hero, MonkEnergy.class).abilityUsed(DragonKick.this); + + if (empowered){ + for (Char ch : Actor.chars()){ + if (ch != enemy + && ch.alignment == Char.Alignment.ENEMY + && Dungeon.level.adjacent(ch.pos, hero.pos)){ + //trace a ballistica to our target (which will also extend past them + Ballistica trajectory = new Ballistica(hero.pos, ch.pos, Ballistica.STOP_TARGET); + //trim it to just be the part that goes past them + trajectory = new Ballistica(trajectory.collisionPos, trajectory.path.get(trajectory.path.size() - 1), Ballistica.PROJECTILE); + //knock them back along that ballistica + WandOfBlastWave.throwChar(ch, trajectory, 6, true, false, hero.getClass()); + + if (trajectory.dist > 0) { + Buff.affect(ch, Paralysis.class, Math.min( 6, trajectory.dist)); + } + } + } + } } }); } @@ -530,8 +578,18 @@ public class MonkEnergy extends Buff implements ActionIndicator.Action { } } + if (Buff.affect(hero, MonkEnergy.class).abilitiesEmpowered(hero)){ + int toHeal = Math.round((hero.HT - hero.HP)/5f); + if (toHeal > 0) { + Buff.affect(hero, Healing.class).setHeal(toHeal, 0, 1); + } + Buff.affect(hero, MeditateResistance.class, 5f); + } + hero.spendAndNext(5f); } + + public static class MeditateResistance extends FlavourBuff{}; } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Belongings.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Belongings.java index fa4a8fd87..48bb25f0e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Belongings.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Belongings.java @@ -99,7 +99,6 @@ public class Belongings implements Iterable { public KindOfWeapon attackingWeapon(){ if (thrownWeapon != null) return thrownWeapon; if (abilityWeapon != null) return abilityWeapon; - if (owner.buff(MonkEnergy.MonkAbility.UnarmedAbilityTracker.class) != null) return null; return weapon(); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java index b97735194..653b87aa3 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java @@ -605,7 +605,7 @@ public class Hero extends Char { if (!(wep instanceof MissileWeapon)) dmg += RingOfForce.armedDamageBonus(this); } else { dmg = RingOfForce.damageRoll(this); - if (RingOfForce.unarmedGetsWeaponEffects(this)){ + if (RingOfForce.unarmedGetsWeaponAugment(this)){ dmg = ((Weapon)belongings.attackingWeapon()).augment.damageFactor(dmg); } } @@ -712,7 +712,7 @@ public class Hero extends Char { //This is for that one guy, you shall get your fists of fury! delay *= 1f/RingOfFuror.attackSpeedMultiplier(this); - if (RingOfForce.unarmedGetsWeaponEffects(this)){ + if (RingOfForce.unarmedGetsWeaponAugment(this)){ delay = ((Weapon)belongings.weapon).augment.delayFactor(delay); } @@ -1274,8 +1274,12 @@ public class Hero extends Char { public int attackProc( final Char enemy, int damage ) { damage = super.attackProc( enemy, damage ); - //procs with weapon even in brawler's stance - KindOfWeapon wep = belongings.attackingWeapon(); + KindOfWeapon wep; + if (RingOfForce.fightingUnarmed(this) && !RingOfForce.unarmedGetsWeaponEnchantment(this)){ + wep = null; + } else { + wep = belongings.attackingWeapon(); + } if (wep != null) damage = wep.proc( this, enemy, damage ); @@ -1355,6 +1359,10 @@ public class Hero extends Char { if (buff(ScrollOfChallenge.ChallengeArena.class) != null){ dmg *= 0.67f; } + //and to monk meditate damage reduction + if (buff(MonkEnergy.MonkAbility.Meditate.MeditateResistance.class) != null){ + dmg *= 0.2f; + } } CapeOfThorns.Thorns thorns = buff( CapeOfThorns.Thorns.class ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/rings/RingOfForce.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/rings/RingOfForce.java index 938bc52e5..69d38d3aa 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/rings/RingOfForce.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/rings/RingOfForce.java @@ -197,7 +197,8 @@ public class RingOfForce extends Ring { } public static boolean fightingUnarmed( Hero hero ){ - if (hero.belongings.attackingWeapon() == null){ + if (hero.belongings.attackingWeapon() == null + || hero.buff(MonkEnergy.MonkAbility.UnarmedAbilityTracker.class) != null){ return true; } if (hero.belongings.thrownWeapon != null || hero.belongings.abilityWeapon != null){ @@ -217,10 +218,25 @@ public class RingOfForce extends Ring { return false; } - public static boolean unarmedGetsWeaponEffects( Hero hero ){ + public static boolean unarmedGetsWeaponEnchantment( Hero hero ){ if (hero.belongings.attackingWeapon() == null){ return false; } + if (hero.buff(MonkEnergy.MonkAbility.UnarmedAbilityTracker.class) != null){ + return hero.buff(MonkEnergy.MonkAbility.FlurryEmpowerTracker.class) != null; + } + BrawlersStance stance = hero.buff(BrawlersStance.class); + if (stance != null && stance.hitsLeft() > 0){ + return true; + } + return false; + } + + public static boolean unarmedGetsWeaponAugment(Hero hero ){ + if (hero.belongings.attackingWeapon() == null + || hero.buff(MonkEnergy.MonkAbility.UnarmedAbilityTracker.class) != null){ + return false; + } BrawlersStance stance = hero.buff(BrawlersStance.class); if (stance != null && stance.hitsLeft() > 0){ return true; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/Weapon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/Weapon.java index c247fe209..baf14c6c2 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/Weapon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/Weapon.java @@ -56,7 +56,6 @@ import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Shocki import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Unstable; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Vampiric; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.RunicBlade; -import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Scimitar; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; @@ -214,8 +213,11 @@ abstract public class Weapon extends KindOfWeapon { @Override public int reachFactor(Char owner) { int reach = RCH; - if (owner instanceof Hero && RingOfForce.unarmedGetsWeaponEffects((Hero) owner)){ + if (owner instanceof Hero && RingOfForce.fightingUnarmed((Hero) owner)){ reach = 1; //brawlers stance benefits from enchantments, but not innate reach + if (!RingOfForce.unarmedGetsWeaponEnchantment((Hero) owner)){ + return reach; + } } if (hasEnchant(Projecting.class, owner)){ return reach + Math.round(enchantment.procChanceMultiplier(owner));