From 6d8402824bf4450f1511c668b4edc754062cf3f8 Mon Sep 17 00:00:00 2001
From: Evan Debenham <Evan@ShatteredPixel.com>
Date: Tue, 27 Apr 2021 17:15:17 -0400
Subject: [PATCH] v0.9.3: Balance changes to the Huntress' talents: - Nature's
 bounty is now more consistent in how it drops berries - Rejuvenating steps
 now starts producing furrowed grass after not gaining exp for a while -
 Farsight now applies to the vision range from heightened senses - shared
 upgrades damage boost increased to 10/20/30% from 7/12/20% - barkskin now
 grants 50/100/150% of your level, which fades every turn

---
 .../assets/messages/actors/actors.properties  |  8 +++----
 .../actors/buffs/Barkskin.java                |  4 +++-
 .../actors/hero/Hero.java                     |  8 ++++++-
 .../actors/hero/Talent.java                   |  1 +
 .../shatteredpixeldungeon/levels/Level.java   | 10 ++++++++-
 .../levels/features/HighGrass.java            | 22 ++++++++++++++-----
 6 files changed, 41 insertions(+), 12 deletions(-)

diff --git a/core/src/main/assets/messages/actors/actors.properties b/core/src/main/assets/messages/actors/actors.properties
index a96651b12..301d26706 100644
--- a/core/src/main/assets/messages/actors/actors.properties
+++ b/core/src/main/assets/messages/actors/actors.properties
@@ -637,7 +637,7 @@ actors.hero.talent.invigorating_meal.desc=_+1:_ Eating food takes the Huntress 1
 actors.hero.talent.restored_nature.title=restored nature
 actors.hero.talent.restored_nature.desc=_+1:_ Drinking a potion of healing spawns _up to 5 grass_ around the Huntress, and roots adjacent enemies for _2 turns_.\n\n_+2:_ Drinking a potion of healing spawns _up to 8 grass_ around the Huntress, and roots adjacent enemies for _3 turns_.\n\nThis talent also triggers when drinking potions or elixirs based on potions of healing.
 actors.hero.talent.rejuvenating_steps.title=rejuvenating steps
-actors.hero.talent.rejuvenating_steps.desc=_+1:_ When the Huntress steps on short grass or embers, they spring up into tall grass which the Huntress immediately furrows. This has a _10 turn cooldown_.\n\n_+2:_ When the Huntress steps on short grass or embers, they spring up into tall grass which the Huntress immediately furrows. This has a _5 turn cooldown_.
+actors.hero.talent.rejuvenating_steps.desc=_+1:_ When the Huntress steps on short grass or embers, they spring up into tall grass which the Huntress immediately furrows. This has a _10 turn cooldown_.\n\n_+2:_ When the Huntress steps on short grass or embers, they spring up into tall grass which the Huntress immediately furrows. This has a _5 turn cooldown_.\n\nThis talent will produce furrowed grass if passive regeneration effects are disabled or the hero has not gained exp in a long time.
 actors.hero.talent.heightened_senses.title=heightened senses
 actors.hero.talent.heightened_senses.desc=_+1:_ The Huntress gains mind vision on any enemy within _2 tiles of her position_.\n\n_+2:_ The Huntress gains mind vision on any enemy within _3 tiles of her position_.
 actors.hero.talent.durable_projectiles.title=durable projectiles
@@ -649,16 +649,16 @@ actors.hero.talent.seer_shot.title=seer shot
 actors.hero.talent.seer_shot.desc=_+1:_ When the Huntress fires an arrow at the ground, it grants vision in a 3x3 area around it for _5 turns_. This has a 20 turn cooldown.\n\n_+2:_ When the Huntress fires an arrow at the ground, it grants vision in a 3x3 area around it for _10 turns_. This has a 20 turn cooldown.\n\n_+3:_ When the Huntress fires an arrow at the ground, it grants vision in a 3x3 area around it for _15 turns_. This has a 20 turn cooldown.
 
 actors.hero.talent.farsight.title=farsight
-actors.hero.talent.farsight.desc=_+1:_ The Sniper's vision range is _increased by 25%_.\n\n_+2:_ The Sniper's vision range is _increased by 50%_.\n\n_+3:_ The Sniper's vision range is _increased by 75%_.
+actors.hero.talent.farsight.desc=_+1:_ The Sniper's vision range is _increased by 25%_.\n\n_+2:_ The Sniper's vision range is _increased by 50%_.\n\n_+3:_ The Sniper's vision range is _increased by 75%_.\n\nThis bonus also applies to mind vision ranged by the Heightened Senses talent.
 actors.hero.talent.shared_enchantment.title=shared enchantment
 actors.hero.talent.shared_enchantment.desc=_+1:_ Thrown weapons have a _33% chance_ to use the enchantment on the Sniper's bow.\n\n_+2:_ Thrown weapons have a _67% chance_ to use the enchantment on the Sniper's bow.\n\n_+3:_ Thrown weapons have a _100% chance_ to use the enchantment on the Sniper's bow.\n\nThis talent does not apply to darts shot from an enchanted crossbow, they already trigger the crossbow's enchantment.
 actors.hero.talent.shared_upgrades.title=shared upgrades
-actors.hero.talent.shared_upgrades.desc=_+1:_ When the Sniper attacks with an upgraded thrown weapon, each level increases the duration of sniper's mark by 1 turn and the damage of her special attack by _7%_.\n\n_+2:_ When the Sniper attacks with an upgraded thrown weapon, each level increases the duration of sniper's mark by 1 turn and the damage of her special attack by _13%_.\n\n_+3:_ When the Sniper attacks with an upgraded thrown weapon, each level increases the duration of sniper's mark by 1 turn and the damage of her special attack by _20%_.
+actors.hero.talent.shared_upgrades.desc=_+1:_ When the Sniper attacks with an upgraded thrown weapon, each level increases the duration of sniper's mark by 1 turn and the damage of her special attack by _10%_.\n\n_+2:_ When the Sniper attacks with an upgraded thrown weapon, each level increases the duration of sniper's mark by 1 turn and the damage of her special attack by _20%_.\n\n_+3:_ When the Sniper attacks with an upgraded thrown weapon, each level increases the duration of sniper's mark by 1 turn and the damage of her special attack by _30%_.
 
 actors.hero.talent.durable_tips.title=durable tips
 actors.hero.talent.durable_tips.desc=_+1:_ Tipped darts have _2x durability_ when the Warden uses them.\n\n_+2:_ Tipped darts have _3x durability_ when the Warden uses them.\n\n_+3:_ Tipped darts have _4x durability_ when the Warden uses them.
 actors.hero.talent.barkskin.title=barkskin
-actors.hero.talent.barkskin.desc=_+1:_ When stepping in grass, the Warden gains barkskin equivalent to her level which fades every _1 turn_.\n\n_+2:_ When stepping in grass, the Warden gains barkskin equivalent to her level which fades every _2 turns_.\n\n_+3:_ When stepping in grass, the Warden gains barkskin equivalent to her level which fades every _3 turns_.
+actors.hero.talent.barkskin.desc=_+1:_ When stepping in grass, the Warden gains barkskin equivalent to _50% of her level_ which fades every turn.\n\n_+2:_ When stepping in grass, the Warden gains barkskin equivalent to _100% of her level_ which fades every turn.\n\n_+3:_ When stepping in grass, the Warden gains barkskin equivalent to _150% of her level_ which fades every turn.
 actors.hero.talent.shielding_dew.title=shielding dew
 actors.hero.talent.shielding_dew.desc=_+1:_ Dewdrops can shield the Warden when her health is full, up to _20% of her max HP_.\n\n_+2:_ Dewdrops can shield the Warden when her health is full, up to _40% of her max HP_.\n\n_+3:_ Dewdrops can shield the Warden when her health is full, up to _60% of her max HP_.actors.hero.talent.hearty_meal.title=hearty meal
 
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Barkskin.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Barkskin.java
index a833461f7..591df5983 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Barkskin.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Barkskin.java
@@ -22,6 +22,7 @@
 package com.shatteredpixel.shatteredpixeldungeon.actors.buffs;
 
 import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
+import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
 import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
 import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
 import com.watabou.utils.Bundle;
@@ -74,7 +75,8 @@ public class Barkskin extends Buff {
 	@Override
 	public float iconFadePercent() {
 		if (target instanceof Hero){
-			float max = ((Hero) target).lvl;
+			float max = ((Hero) target).lvl*((Hero) target).pointsInTalent(Talent.BARKSKIN)/2;
+			max = Math.max(max, 2+((Hero) target).lvl/3);
 			return Math.max(0, (max-level)/max);
 		}
 		return 0;
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 6184dcd7c..e7d1e1523 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
@@ -685,7 +685,7 @@ public class Hero extends Char {
 		}
 		
 		if(hasTalent(Talent.BARKSKIN) && Dungeon.level.map[pos] == Terrain.FURROWED_GRASS){
-			Buff.affect(this, Barkskin.class).set( lvl, pointsInTalent(Talent.BARKSKIN) );
+			Buff.affect(this, Barkskin.class).set( (lvl*pointsInTalent(Talent.BARKSKIN))/2, 1 );
 		}
 		
 		return actResult;
@@ -1461,6 +1461,12 @@ public class Hero extends Char {
 			for (Item i : belongings) {
 				i.onHeroGainExp(percent, this);
 			}
+			if (buff(Talent.RejuvenatingStepsFurrow.class) != null){
+				buff(Talent.RejuvenatingStepsFurrow.class).countDown(percent*200f);
+				if (buff(Talent.RejuvenatingStepsFurrow.class).count() <= 0){
+					buff(Talent.RejuvenatingStepsFurrow.class).detach();
+				}
+			}
 		}
 		
 		boolean levelUp = false;
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 238691c2a..c76b1a866 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
@@ -142,6 +142,7 @@ public enum Talent {
 	public static class EmpoweredStrikeTracker extends FlavourBuff{};
 	public static class BountyHunterTracker extends FlavourBuff{};
 	public static class RejuvenatingStepsCooldown extends FlavourBuff{};
+	public static class RejuvenatingStepsFurrow extends CounterBuff{};
 	public static class SeerShotCooldown extends FlavourBuff{};
 
 	int icon;
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java
index e23d9f102..1330e494d 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/Level.java
@@ -942,8 +942,11 @@ public abstract class Level implements Bundlable {
 
 			if (Dungeon.hero.buff(LockedFloor.class) != null && !Dungeon.hero.buff(LockedFloor.class).regenOn()){
 				set(ch.pos, Terrain.FURROWED_GRASS);
+			} else if (ch.buff(Talent.RejuvenatingStepsFurrow.class) != null && ch.buff(Talent.RejuvenatingStepsFurrow.class).count() >= 200) {
+				set(ch.pos, Terrain.FURROWED_GRASS);
 			} else {
 				set(ch.pos, Terrain.HIGH_GRASS);
+				Buff.count(ch, Talent.RejuvenatingStepsFurrow.class, 3 - Dungeon.hero.pointsInTalent(Talent.REJUVENATING_STEPS));
 			}
 			GameScene.updateMap(ch.pos);
 			Buff.affect(ch, Talent.RejuvenatingStepsCooldown.class, 15f - 5f*Dungeon.hero.pointsInTalent(Talent.REJUVENATING_STEPS));
@@ -1141,9 +1144,14 @@ public abstract class Level implements Bundlable {
 					}
 				}
 			} else if (((Hero) c).hasTalent(Talent.HEIGHTENED_SENSES)) {
+				Hero h = (Hero) c;
+				int range = 1+h.pointsInTalent(Talent.HEIGHTENED_SENSES);
+				if (h.hasTalent(Talent.FARSIGHT)){
+					range = (int)Math.floor( range * (1f + 0.25f*h.pointsInTalent(Talent.FARSIGHT)));
+				}
 				for (Mob mob : mobs) {
 					int p = mob.pos;
-					if (!fieldOfView[p] && distance(c.pos, p) <= 1+((Hero) c).pointsInTalent(Talent.HEIGHTENED_SENSES)) {
+					if (!fieldOfView[p] && distance(c.pos, p) <= range) {
 						for (int i : PathFinder.NEIGHBOURS9) {
 							heroMindFov[mob.pos + i] = true;
 						}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/features/HighGrass.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/features/HighGrass.java
index bef98c0c1..2d463ab15 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/features/HighGrass.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/features/HighGrass.java
@@ -85,15 +85,27 @@ public class HighGrass {
 					}
 				}
 
+				//berries try to drop on floors 2/3/4/6/7/8, to a max of 4/6
 				Talent.NatureBerriesAvailable berries = ch.buff(Talent.NatureBerriesAvailable.class);
-				if (berries != null && Random.Int(30) == 0){
-					if (berries.count() > 0){
+				if (berries != null) {
+					int targetFloor = 2 + 2*((Hero)ch).pointsInTalent(Talent.NATURES_BOUNTY);
+					targetFloor -= berries.count();
+					targetFloor += (targetFloor >= 5) ? 3 : 2;
+
+					//If we're behind: 1/10, if we're on page: 1/30, if we're ahead: 1/90
+					boolean droppingBerry = false;
+					if (Dungeon.depth > targetFloor)        droppingBerry = Random.Int(10) == 0;
+					else if (Dungeon.depth == targetFloor)  droppingBerry = Random.Int(30) == 0;
+					else if (Dungeon.depth < targetFloor)   droppingBerry = Random.Int(90) == 0;
+
+					if (droppingBerry){
 						berries.countDown(1);
 						level.drop(new Berry(), pos).sprite.drop();
+						if (berries.count() <= 0){
+							berries.detach();
+						}
 					}
-					if (berries.count() <= 0){
-						berries.detach();
-					}
+
 				}
 			}