diff --git a/core/src/main/assets/messages/actors/actors.properties b/core/src/main/assets/messages/actors/actors.properties
index f9efc7f93..5207fa3fe 100644
--- a/core/src/main/assets/messages/actors/actors.properties
+++ b/core/src/main/assets/messages/actors/actors.properties
@@ -369,11 +369,11 @@ actors.hero.abilities.rogue.shadowclone.name=shadow clone
actors.hero.abilities.rogue.shadowclone.short_desc=The Rogue summons a _Shadow Clone_, which is frail, but can be directed and deals damage based on his weapon.
actors.hero.abilities.rogue.shadowclone.desc=TODO
actors.hero.abilities.huntress.spectralblades.name=spectral blades
-actors.hero.abilities.huntress.spectralblades.short_desc=The Huntress throws a _Spectral Blade_ at a target, inflicting damage depending on her currently equipped melee weapon.
+actors.hero.abilities.huntress.spectralblades.short_desc=The Huntress throws _Spectral Blades_ at a target, inflicting damage depending on her currently equipped melee weapon.
actors.hero.abilities.huntress.spectralblades.desc=TODO
-actors.hero.abilities.huntress.naturesstrength.name=Nature's Strength
-actors.hero.abilities.huntress.naturesstrength.short_desc=The Huntress calls upon _Nature's Strength_ to empower her, increasing her movement speed and her bow's rate of fire for a short time.
-actors.hero.abilities.huntress.naturesstrength.desc=TODO
+actors.hero.abilities.huntress.naturespower.name=nature's power
+actors.hero.abilities.huntress.naturespower.short_desc=The Huntress calls upon _Nature's Power_, increasing her movement speed and her bow's rate of fire for a short time.
+actors.hero.abilities.huntress.naturespower.desc=TODO
actors.hero.abilities.huntress.spirithawk.name=spirit hawk
actors.hero.abilities.huntress.spirithawk.short_desc=The Huntress summons a _Spirit Hawk_ familiar, which can help her scout locations and distract enemies.
actors.hero.abilities.huntress.spirithawk.desc=TODO
@@ -676,19 +676,19 @@ actors.hero.talent.projecting_blades.desc=_+1:_ Spectral blades has _+25% accura
actors.hero.talent.spirit_blades.title=spirit blades
actors.hero.talent.spirit_blades.desc=_+1:_ Spectral blades has a _25% chance_ to also use the enchantment on the spirit bow.\n\n_+2:_ Spectral blades has a _50% chance_ to also use the enchantment on the spirit bow.\n\n_+3:_ Spectral blades has a _75% chance_ to also use the enchantment on the spirit bow.\n\n_+4:_ Spectral blades has a _100% chance_ to also use the enchantment on the spirit bow.
-actors.hero.talent.huntress_2_1.title=TODO NAME
-actors.hero.talent.huntress_2_1.desc=TODO DESC
-actors.hero.talent.huntress_2_2.title=TODO NAME
-actors.hero.talent.huntress_2_2.desc=TODO DESC
-actors.hero.talent.huntress_2_3.title=TODO NAME
-actors.hero.talent.huntress_2_3.desc=TODO DESC
+actors.hero.talent.growing_power.title=growing power
+actors.hero.talent.growing_power.desc=_+1:_ The attack and movespeed boosts from nature's power are increased to _38% and 125%_, from 33% and 100%.\n\n_+2:_ The attack and movespeed boosts from nature's power are increased to _42% and 150%_, from 33% and 50%.\n\n_+3:_ The attack and movespeed boosts from nature's power are increased to _46% and 150%_, from 33% and 100%.\n\n_+4:_ The attack and movespeed boosts from nature's power are increased to _50% and 200%_, from 33% and 100%.
+actors.hero.talent.natures_wrath.title=nature's wrath
+actors.hero.talent.natures_wrath.desc=_+1:_ While nature's power is active, shots from the spirit bow have an _8% chance_ to trigger a random harmful plant effect.\n\n_+2:_ While nature's power is active, shots from the spirit bow have a _17% chance_ to trigger a random harmful plant effect.\n\n_+3:_ While nature's power is active, shots from the spirit bow have an _25% chance_ to trigger a random harmful plant effect.\n\n_+4:_ While nature's power is active, shots from the spirit bow have a _33% chance_ to trigger a random harmful plant effect.\n\nThe plants that can be triggered are: blindweed, firebloom, icecap, sorrowmoss, and stormvine.
+actors.hero.talent.wild_momentum.title=wild momentum
+actors.hero.talent.wild_momentum.desc=_+1:_ Killing an enemy with the spirit bow prolongs the duration of nature's power by _1 turn_. The duration can be extended by a max of _2 turns_.\n\n_+2:_ Killing an enemy with the spirit bow prolongs the duration of nature's power by _2 turns_. The duration can be extended by a max of _4 turns_.\n\n_+3:_ Killing an enemy with the spirit bow prolongs the duration of nature's power by _3 turns_. The duration can be extended by a max of _6 turns_.\n\n_+4:_ Killing an enemy with the spirit bow prolongs the duration of nature's power by _4 turns_. The duration can be extended by a max of _8 turns_.
actors.hero.talent.huntress_3_1.title=TODO NAME
-actors.hero.talent.huntress_3_1.desc=TODO DESC
+actors.hero.talent.huntress_3_1.desc=_+1:_ \n\n_+2:_ \n\n_+3:_ \n\n_+4:_
actors.hero.talent.huntress_3_2.title=TODO NAME
-actors.hero.talent.huntress_3_2.desc=TODO DESC
+actors.hero.talent.huntress_3_2.desc=_+1:_ \n\n_+2:_ \n\n_+3:_ \n\n_+4:_
actors.hero.talent.huntress_3_3.title=TODO NAME
-actors.hero.talent.huntress_3_3.desc=TODO DESC
+actors.hero.talent.huntress_3_3.desc=_+1:_ \n\n_+2:_ \n\n_+3:_ \n\n_+4:_
#universal
actors.hero.talent.heroic_energy.title=heroic energy
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 e5e54e955..520222fb3 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
@@ -53,6 +53,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.huntress.NaturesPower;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Monk;
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
@@ -530,6 +531,11 @@ public class Hero extends Char {
} else {
((HeroSprite)sprite).sprint( 1f );
}
+
+ NaturesPower.NaturesStrengthTracker natStrength = buff(NaturesPower.NaturesStrengthTracker.class);
+ if (natStrength != null){
+ speed *= (2f + 0.25f*pointsInTalent(Talent.GROWING_POWER));
+ }
return speed;
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 43be32423..b1085514d 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
@@ -131,8 +131,8 @@ public enum Talent {
DURABLE_TIPS(110, 3), BARKSKIN(111, 3), SHIELDING_DEW(112, 3),
//Spectral Blades T4
FAN_OF_BLADES(113, 4), PROJECTING_BLADES(114, 4), SPIRIT_BLADES(115, 4),
- //??? T4
- HUNTRESS_2_1(116, 4), HUNTRESS_2_2(117, 4), HUNTRESS_2_3(118, 4),
+ //Natures Power T4
+ GROWING_POWER(116, 4), NATURES_WRATH(117, 4), WILD_MOMENTUM(118, 4),
//??? T4
HUNTRESS_3_1(119, 4), HUNTRESS_3_2(120, 4), HUNTRESS_3_3(121, 4),
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/huntress/NaturesPower.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/huntress/NaturesPower.java
new file mode 100644
index 000000000..ee7839c4d
--- /dev/null
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/huntress/NaturesPower.java
@@ -0,0 +1,81 @@
+/*
+ * Pixel Dungeon
+ * Copyright (C) 2012-2015 Oleg Dolya
+ *
+ * Shattered Pixel Dungeon
+ * Copyright (C) 2014-2021 Evan Debenham
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see
+ */
+
+package com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress;
+
+import com.shatteredpixel.shatteredpixeldungeon.Assets;
+import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
+import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
+import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FlavourBuff;
+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.effects.particles.LeafParticle;
+import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor;
+import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
+import com.watabou.noosa.audio.Sample;
+
+public class NaturesPower extends ArmorAbility {
+
+ @Override
+ protected void activate(ClassArmor armor, Hero hero, Integer target) {
+
+ Buff.prolong(hero, NaturesStrengthTracker.class, NaturesStrengthTracker.DURATION);
+ hero.buff(NaturesStrengthTracker.class).extensionsLeft = 2;
+ hero.sprite.operate(hero.pos);
+ Sample.INSTANCE.play(Assets.Sounds.CHARGEUP);
+ hero.sprite.emitter().burst(LeafParticle.GENERAL, 10);
+ hero.spendAndNext(Actor.TICK);
+
+ }
+
+ @Override
+ public Talent[] talents() {
+ return new Talent[]{Talent.GROWING_POWER, Talent.NATURES_WRATH, Talent.WILD_MOMENTUM, Talent.HEROIC_ENERGY};
+ }
+
+ public static class NaturesStrengthTracker extends FlavourBuff{
+
+ public static final float DURATION = 8f;
+
+ public int extensionsLeft = 2;
+
+ public void extend( int turns ){
+ if (extensionsLeft > 0 && turns > 0) {
+ spend(turns);
+ extensionsLeft--;
+ }
+ }
+
+ @Override
+ public int icon() {
+ return BuffIndicator.SHADOWS;
+ }
+
+ @Override
+ public float iconFadePercent() {
+ return Math.max(0, (DURATION - visualcooldown()) / DURATION);
+ }
+
+ //TODO name/desc
+
+ }
+}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/huntress/NaturesStrength.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/huntress/NaturesStrength.java
deleted file mode 100644
index fce6ab799..000000000
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/huntress/NaturesStrength.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Pixel Dungeon
- * Copyright (C) 2012-2015 Oleg Dolya
- *
- * Shattered Pixel Dungeon
- * Copyright (C) 2014-2021 Evan Debenham
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see
- */
-
-package com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress;
-
-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.items.armor.ClassArmor;
-
-public class NaturesStrength extends ArmorAbility {
-
- @Override
- protected void activate(ClassArmor armor, Hero hero, Integer target) {
- //TODO
- }
-
- @Override
- public Talent[] talents() {
- return new Talent[]{Talent.HUNTRESS_2_1, Talent.HUNTRESS_2_2, Talent.HUNTRESS_2_3, Talent.HEROIC_ENERGY};
- }
-}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/SpiritBow.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/SpiritBow.java
index f4a91ba50..f08c0aa22 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/SpiritBow.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/SpiritBow.java
@@ -29,19 +29,29 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.RevealedArea;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
+import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.NaturesPower;
import com.shatteredpixel.shatteredpixeldungeon.effects.Splash;
+import com.shatteredpixel.shatteredpixeldungeon.effects.particles.LeafParticle;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfFuror;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfSharpshooting;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
+import com.shatteredpixel.shatteredpixeldungeon.plants.Blindweed;
+import com.shatteredpixel.shatteredpixeldungeon.plants.Firebloom;
+import com.shatteredpixel.shatteredpixeldungeon.plants.Icecap;
+import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
+import com.shatteredpixel.shatteredpixeldungeon.plants.Sorrowmoss;
+import com.shatteredpixel.shatteredpixeldungeon.plants.Stormvine;
import com.shatteredpixel.shatteredpixeldungeon.scenes.CellSelector;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.shatteredpixel.shatteredpixeldungeon.sprites.MissileSprite;
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton;
import com.watabou.noosa.audio.Sample;
+import com.watabou.noosa.particles.Emitter;
import com.watabou.utils.Callback;
import com.watabou.utils.Random;
+import com.watabou.utils.Reflection;
import java.util.ArrayList;
@@ -83,7 +93,47 @@ public class SpiritBow extends Weapon {
}
}
-
+
+ private static Class[] harmfulPlants = new Class[]{
+ Blindweed.class, Firebloom.class, Icecap.class, Sorrowmoss.class, Stormvine.class
+ };
+
+ @Override
+ public int proc(Char attacker, Char defender, int damage) {
+
+ if (attacker.buff(NaturesPower.NaturesStrengthTracker.class) != null){
+
+ Actor.add(new Actor() {
+ {
+ actPriority = VFX_PRIO;
+ }
+
+ @Override
+ protected boolean act() {
+
+ if (Random.Int(12) < ((Hero)attacker).pointsInTalent(Talent.NATURES_WRATH)){
+ Plant plant = (Plant) Reflection.newInstance(Random.element(harmfulPlants));
+ plant.pos = defender.pos;
+ plant.activate( defender.isAlive() ? defender : null );
+ }
+
+ if (!defender.isAlive()){
+ NaturesPower.NaturesStrengthTracker tracker = attacker.buff(NaturesPower.NaturesStrengthTracker.class);
+ if (tracker != null){
+ tracker.extend(((Hero) attacker).pointsInTalent(Talent.WILD_MOMENTUM));
+ }
+ }
+
+ Actor.remove(this);
+ return true;
+ }
+ });
+
+ }
+
+ return super.proc(attacker, defender, damage);
+ }
+
@Override
public String info() {
String info = desc();
@@ -199,7 +249,15 @@ public class SpiritBow extends Weapon {
return 2f * RingOfFuror.attackDelayMultiplier(owner);
}
} else {
- return super.speedFactor(owner);
+
+ float speed = super.speedFactor(owner);
+
+ if (owner.buff(NaturesPower.NaturesStrengthTracker.class) != null){
+ // 1.33x speed to 1.5x speed, depending on talent points
+ speed /= ((32 + ((Hero)owner).pointsInTalent(Talent.GROWING_POWER)) / 24f);
+ }
+
+ return speed;
}
}
@@ -230,7 +288,20 @@ public class SpiritBow extends Weapon {
hitSound = Assets.Sounds.HIT_ARROW;
}
-
+
+ @Override
+ public Emitter emitter() {
+ if (Dungeon.hero.buff(NaturesPower.NaturesStrengthTracker.class) != null){
+ Emitter e = new Emitter();
+ e.pos(5, 5);
+ e.fillTarget = false;
+ e.pour(LeafParticle.GENERAL, 0.01f);
+ return e;
+ } else {
+ return super.emitter();
+ }
+ }
+
@Override
public int damageRoll(Char owner) {
return SpiritBow.this.damageRoll(owner);
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSprite.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSprite.java
index ffc9444e5..5756b02d4 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSprite.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSprite.java
@@ -251,7 +251,10 @@ public class ItemSprite extends MovieClip {
@Override
public void kill() {
super.kill();
- if (emitter != null) emitter.killAndErase();
+ if (emitter != null) {
+ emitter.on = false;
+ emitter.autoKill = true;
+ }
emitter = null;
}