diff --git a/core/src/main/assets/interfaces/buffs.png b/core/src/main/assets/interfaces/buffs.png
index 30c06e58f..cda8b5127 100644
Binary files a/core/src/main/assets/interfaces/buffs.png and b/core/src/main/assets/interfaces/buffs.png differ
diff --git a/core/src/main/assets/interfaces/large_buffs.png b/core/src/main/assets/interfaces/large_buffs.png
index 482a26130..356472bd0 100644
Binary files a/core/src/main/assets/interfaces/large_buffs.png and b/core/src/main/assets/interfaces/large_buffs.png differ
diff --git a/core/src/main/assets/interfaces/talent_icons.png b/core/src/main/assets/interfaces/talent_icons.png
index a2c7a2d11..ca6a8a98f 100644
Binary files a/core/src/main/assets/interfaces/talent_icons.png and b/core/src/main/assets/interfaces/talent_icons.png differ
diff --git a/core/src/main/assets/messages/actors/actors.properties b/core/src/main/assets/messages/actors/actors.properties
index dec11a70b..613dab26c 100644
--- a/core/src/main/assets/messages/actors/actors.properties
+++ b/core/src/main/assets/messages/actors/actors.properties
@@ -303,6 +303,9 @@ actors.buffs.corrosion.desc=Powerful acid melts away flesh, metal, and bone at a
actors.buffs.vertigo.name=Vertigo
actors.buffs.vertigo.desc=Walking in a straight line can be difficult when the whole world is spinning.\n\nWhile under the effects of vertigo, characters who attempt to move will go in a random direction, instead of the one they intended to go in.\n\nTurns of vertigo remaining: %s.
+actors.buffs.wandempower.name=Wands Empowered
+actors.buffs.wandempower.desc=Your damage-dealing wands have been empowered, increasing the amount of damage they deal for a few zaps.\n\nBonus damage: %1$d.\nZaps remaining: %2$d.
+
actors.buffs.weakness.name=Weakened
actors.buffs.weakness.heromsg=You feel weakened!
actors.buffs.weakness.desc=Everything suddenly seems much heavier.\n\nWeakening magic reduces a character's physical strength, causing them to deal 33%% reduced damage.\n\nTurns of weakness remaining: %s.
@@ -321,14 +324,20 @@ actors.hero.talent.test_subject.title=test subject
actors.hero.talent.test_subject.desc=_+1:_ Whenever the Warrior identifies an item, he heals for _2 HP_.\n\n_+2:_ Whenever the Warrior identifies an item, he heals for _3 HP_.
actors.hero.talent.iron_will.title=iron will
actors.hero.talent.iron_will.desc=_+1:_ The max shield provided by the Warrior's seal is _increased by 1_.\n\n_+2:_ The max shield provided by the Warrior's seal is _increased by 2_.
-actors.hero.talent.energizing_meal.title=energizing meal
-actors.hero.talent.energizing_meal.desc=_+1:_ Eating food grants the Mage _5 turns of wand recharging_.\n\n_+2:_ Eating food grants the Mage _8 turns of wand recharging_.
+
+actors.hero.talent.empowering_meal.title=empowering meal
+actors.hero.talent.empowering_meal.desc=_+1:_ Eating food grants the Mage _2 bonus damage_ on his next 3 wand zaps.\n\n_+1:_ Eating food grants the Mage _3 bonus damage_ on his next 3 wand zaps.
actors.hero.talent.scholars_intuition.title=scholar's intuition
actors.hero.talent.scholars_intuition.desc=_+1:_ The Mage identifies wands _3x faster_.\n\n_+2:_ The Mage identifies wands _when he uses them_.
actors.hero.talent.tested_hypothesis.title=tested hypothesis
-actors.hero.talent.tested_hypothesis.desc=_+1:_ Whenever he identifies a scroll by using it, the Mage gains _6 shielding_.\n\n_+2:_ Whenever he identifies a scroll by using it, the Mage gains _9 shielding_.
+actors.hero.talent.tested_hypothesis.desc=_+1:_ Whenever the Mage identifies an item, he gains _2 turns of wand recharging_.\n\n_+2:_ Whenever the Mage identifies an item, he gains _3 turns of wand recharging_.
+actors.hero.talent.backup_barrier.title=backup barrier
+actors.hero.talent.backup_barrier.desc=_+1:_ The Mage gains _3 shielding_ whenever he spends the last charge in his staff.\n\n_+2:_ The Mage gains _5 shielding_ whenever he spends the last charge in his staff.
+actors.hero.talent.energizing_meal.title=energizing meal
+actors.hero.talent.energizing_meal.desc=_+1:_ Eating food grants the Mage _5 turns of wand recharging_.\n\n_+2:_ Eating food grants the Mage _8 turns of wand recharging_.
actors.hero.talent.energizing_upgrade.title=energizing upgrade
actors.hero.talent.energizing_upgrade.desc=_+1:_ The Mage's staff recharges for _1 extra charge_ whenever the Mage upgrades it.\n\n_+2:_ The Mage's staff recharges for _2 extra charges_ whenever the Mage upgrades it.
+
actors.hero.talent.rationed_meal.title=rationed meal
actors.hero.talent.rationed_meal.desc=_+1:_ Eating food gives the Rogue _15% more satiety_.\n\n_+2:_ Eating food gives the Rogue _25% more satiety_.
actors.hero.talent.thiefs_intuition.title=thief's intuition
@@ -337,6 +346,7 @@ actors.hero.talent.sucker_punch.title=sucker punch
actors.hero.talent.sucker_punch.desc=_+1:_ The Rogue deals _1-2 bonus damage_ the first time he surprise attacks an enemy.\n\n_+2:_ The Rogue deals _2 bonus damage_ the first time he surprise attacks an enemy.
actors.hero.talent.mending_shadows.title=mending shadows
actors.hero.talent.mending_shadows.desc=_+1:_ The Rogue heals for 1 HP every _5 consecutive turns_ that he is hidden by his cloak.\n\n_+2:_ The Rogue heals for 1 HP every _3 consecutive turns_ that he is hidden by his cloak.
+
actors.hero.talent.invigorating_meal.title=invigorating meal
actors.hero.talent.invigorating_meal.desc=_+1:_ Eating food takes 1 turn and grants the Huntress _1 turn of haste_.\n\n_+2:_ Eating food takes 1 turn and grants the Huntress _2 turns of haste_.
actors.hero.talent.survivalists_intuition.title=survivalist's intuition
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/WandEmpower.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/WandEmpower.java
new file mode 100644
index 000000000..59663f865
--- /dev/null
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/WandEmpower.java
@@ -0,0 +1,85 @@
+/*
+ * Pixel Dungeon
+ * Copyright (C) 2012-2015 Oleg Dolya
+ *
+ * Shattered Pixel Dungeon
+ * Copyright (C) 2014-2020 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.buffs;
+
+import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
+import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
+import com.watabou.noosa.Image;
+import com.watabou.utils.Bundle;
+
+public class WandEmpower extends Buff {
+
+ {
+ type = buffType.POSITIVE;
+ }
+
+ @Override
+ public int icon() {
+ return BuffIndicator.UPGRADE;
+ }
+
+ @Override
+ public void tintIcon(Image icon) {
+ icon.hardlight(1, 1, 0);
+ }
+
+ @Override
+ public float iconFadePercent() {
+ return Math.max(0, (3-left) / 3f);
+ }
+
+ @Override
+ public String toString() {
+ return Messages.get(this, "name");
+ }
+
+ @Override
+ public String desc() {
+ return Messages.get(this, "desc", dmgBoost, left);
+ }
+
+ public int dmgBoost;
+ public int left;
+
+ public void set(int dmg, int shots){
+ dmgBoost = dmg;
+ left = Math.max(left, shots);
+ }
+
+ private static final String BOOST = "boost";
+ private static final String LEFT = "left";
+
+ @Override
+ public void storeInBundle(Bundle bundle) {
+ super.storeInBundle(bundle);
+ bundle.put( BOOST, dmgBoost );
+ bundle.put( LEFT, left );
+ }
+
+ @Override
+ public void restoreFromBundle(Bundle bundle) {
+ super.restoreFromBundle(bundle);
+ dmgBoost = bundle.getInt( BOOST );
+ left = bundle.getInt( LEFT );
+ }
+
+}
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 40a7a101b..e187a1a5c 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
@@ -24,17 +24,16 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.hero;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
-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.Hunger;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Recharging;
+import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.WandEmpower;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring;
-import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRecharging;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
@@ -62,12 +61,12 @@ public enum Talent {
TEST_WARRIOR_T2_4(7),
TEST_WARRIOR_T2_5(8),
- ENERGIZING_MEAL(16),
+ EMPOWERING_MEAL(16),
SCHOLARS_INTUITION(17),
TESTED_HYPOTHESIS(18),
- ENERGIZING_UPGRADE(19),
- TEST_MAGE_T2_1(20),
- TEST_MAGE_T2_2(21),
+ BACKUP_BARRIER(19),
+ ENERGIZING_MEAL(20),
+ ENERGIZING_UPGRADE(21),
TEST_MAGE_T2_3(22),
TEST_MAGE_T2_4(23),
TEST_MAGE_T2_5(24),
@@ -149,6 +148,11 @@ public enum Talent {
hero.sprite.emitter().burst(Speck.factory(Speck.HEALING), 1+hero.pointsInTalent(HEARTY_MEAL));
}
}
+ if (hero.hasTalent(EMPOWERING_MEAL)){
+ //2/3 bonus wand damage for next 3 zaps
+ Buff.affect( hero, WandEmpower.class).set(1 + hero.pointsInTalent(EMPOWERING_MEAL), 3);
+ ScrollOfRecharging.charge( hero );
+ }
if (hero.hasTalent(ENERGIZING_MEAL)){
//5/8 turns of recharging
Buff.affect( hero, Recharging.class, 2 + 3*(hero.pointsInTalent(ENERGIZING_MEAL)) );
@@ -213,8 +217,9 @@ public enum Talent {
Emitter e = hero.sprite.emitter();
if (e != null) e.burst(Speck.factory(Speck.HEALING), hero.pointsInTalent(TEST_SUBJECT));
}
- if (item instanceof Scroll && hero.hasTalent(TESTED_HYPOTHESIS)){
- Buff.affect(hero, Barrier.class).setShield(3 + (3 * hero.pointsInTalent(Talent.TESTED_HYPOTHESIS)), 1);
+ if (hero.hasTalent(TESTED_HYPOTHESIS)){
+ //2/3 turns of wand recharging
+ Buff.affect(hero, Recharging.class, 1f + hero.pointsInTalent(TESTED_HYPOTHESIS));
ScrollOfRecharging.charge(hero);
}
}
@@ -264,7 +269,7 @@ public enum Talent {
Collections.addAll(tierTalents, HEARTY_MEAL, ARMSMASTERS_INTUITION, TEST_SUBJECT, IRON_WILL);
break;
case MAGE:
- Collections.addAll(tierTalents, ENERGIZING_MEAL, SCHOLARS_INTUITION, TESTED_HYPOTHESIS, ENERGIZING_UPGRADE);
+ Collections.addAll(tierTalents, EMPOWERING_MEAL, SCHOLARS_INTUITION, TESTED_HYPOTHESIS, BACKUP_BARRIER);
break;
case ROGUE:
Collections.addAll(tierTalents, RATIONED_MEAL, THIEFS_INTUITION, SUCKER_PUNCH, MENDING_SHADOWS);
@@ -284,7 +289,7 @@ public enum Talent {
Collections.addAll(tierTalents, TEST_WARRIOR_T2_1, TEST_WARRIOR_T2_2, TEST_WARRIOR_T2_3, TEST_WARRIOR_T2_4, TEST_WARRIOR_T2_5);
break;
case MAGE:
- Collections.addAll(tierTalents, TEST_MAGE_T2_1, TEST_MAGE_T2_2, TEST_MAGE_T2_3, TEST_MAGE_T2_4, TEST_MAGE_T2_5);
+ Collections.addAll(tierTalents, ENERGIZING_MEAL, ENERGIZING_UPGRADE, TEST_MAGE_T2_3, TEST_MAGE_T2_4, TEST_MAGE_T2_5);
break;
case ROGUE:
Collections.addAll(tierTalents, TEST_ROGUE_T2_1, TEST_ROGUE_T2_2, TEST_ROGUE_T2_3, TEST_ROGUE_T2_4, TEST_ROGUE_T2_5);
@@ -307,32 +312,41 @@ public enum Talent {
//Nothing here yet. Hm.....
}
- private static final String TALENTS = "talents";
+ private static final String TALENT_TIER = "talents_tier_";
public static void storeTalentsInBundle( Bundle bundle, Hero hero ){
- Bundle talentBundle = new Bundle();
+ for (int i = 0; i < MAX_TALENT_TIERS; i++){
+ LinkedHashMap tier = hero.talents.get(i);
+ Bundle tierBundle = new Bundle();
- for (Talent talent : values()){
- if (hero.hasTalent(talent)){
- talentBundle.put(talent.name(), hero.pointsInTalent(talent));
+ for (Talent talent : tier.keySet()){
+ if (tier.get(talent) > 0){
+ tierBundle.put(talent.name(), tier.get(talent));
+ }
+ if (tierBundle.contains(talent.name())){
+ tier.put(talent, Math.min(tierBundle.getInt(talent.name()), talent.maxPoints()));
+ }
}
+ bundle.put(TALENT_TIER+(i+1), tierBundle);
}
-
- bundle.put(TALENTS, talentBundle);
}
public static void restoreTalentsFromBundle( Bundle bundle, Hero hero ){
if (hero.heroClass != null) initClassTalents(hero);
if (hero.subClass != null) initSubclassTalents(hero);
- if (!bundle.contains(TALENTS)) return;
- Bundle talentBundle = bundle.getBundle(TALENTS);
+ for (int i = 0; i < MAX_TALENT_TIERS; i++){
+ LinkedHashMap tier = hero.talents.get(i);
+ Bundle tierBundle = bundle.contains(TALENT_TIER+(i+1)) ? bundle.getBundle(TALENT_TIER+(i+1)) : null;
+ //pre-0.9.1 saves
+ if (tierBundle == null && i == 0 && bundle.contains("talents")){
+ tierBundle = bundle.getBundle("talents");
+ }
- for (Talent talent : values()){
- if (talentBundle.contains(talent.name())){
- for (LinkedHashMap tier : hero.talents){
- if (tier.containsKey(talent)){
- tier.put(talent, Math.min(talentBundle.getInt(talent.name()), talent.maxPoints()));
+ if (tierBundle != null){
+ for (Talent talent : tier.keySet()){
+ if (tierBundle.contains(talent.name())){
+ tier.put(talent, Math.min(tierBundle.getInt(talent.name()), talent.maxPoints()));
}
}
}
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/DamageWand.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/DamageWand.java
index e02d73fc4..fc36bbd3b 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/DamageWand.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/DamageWand.java
@@ -21,7 +21,11 @@
package com.shatteredpixel.shatteredpixeldungeon.items.wands;
+import com.shatteredpixel.shatteredpixeldungeon.Assets;
+import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
+import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.WandEmpower;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
+import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Random;
//for wands that directly damage a target
@@ -41,11 +45,21 @@ public abstract class DamageWand extends Wand{
public abstract int max(int lvl);
public int damageRoll(){
- return Random.NormalIntRange(min(), max());
+ return damageRoll(buffedLvl());
}
public int damageRoll(int lvl){
- return Random.NormalIntRange(min(lvl), max(lvl));
+ int dmg = Random.NormalIntRange(min(lvl), max(lvl));
+ WandEmpower emp = Dungeon.hero.buff(WandEmpower.class);
+ if (emp != null){
+ dmg += emp.dmgBoost;
+ emp.left--;
+ if (emp.left <= 0) {
+ emp.detach();
+ }
+ Sample.INSTANCE.play(Assets.Sounds.HIT_STRONG, 0.75f, 1.2f);
+ }
+ return dmg;
}
@Override
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/Wand.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/Wand.java
index 706c8e35f..bfb3667b8 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/Wand.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/Wand.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.Barrier;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LockedFloor;
@@ -343,6 +344,15 @@ public abstract class Wand extends Item {
buff.detach();
}
+ //if the wand is owned by the hero, but not in their inventory, it must be in the staff
+ if (curCharges == 0
+ && charger.target == Dungeon.hero
+ && !Dungeon.hero.belongings.contains(this)
+ && Dungeon.hero.hasTalent(Talent.BACKUP_BARRIER)){
+ //grants 3/5 shielding
+ Buff.affect(Dungeon.hero, Barrier.class).setShield(1 + 2*Dungeon.hero.pointsInTalent(Talent.BACKUP_BARRIER));
+ }
+
Invisibility.dispel();
updateQuickslot();
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfMagicMissile.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfMagicMissile.java
index c254c6862..7dbe63670 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfMagicMissile.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfMagicMissile.java
@@ -119,7 +119,7 @@ public class WandOfMagicMissile extends DamageWand {
@Override
public int icon() {
- return BuffIndicator.RECHARGING;
+ return BuffIndicator.UPGRADE;
}
@Override
diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java
index 1c19a5d38..061df9eaa 100644
--- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java
+++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java
@@ -95,6 +95,7 @@ public class BuffIndicator extends Component {
public static final int HEX = 47;
public static final int DEGRADE = 48;
public static final int PINCUSHION = 49;
+ public static final int UPGRADE = 50;
public static final int SIZE = 7;