diff --git a/core/src/main/assets/messages/items/items.properties b/core/src/main/assets/messages/items/items.properties index 3a1f640b2..7f1efefbc 100644 --- a/core/src/main/assets/messages/items/items.properties +++ b/core/src/main/assets/messages/items/items.properties @@ -734,8 +734,11 @@ items.potions.exotic.potionofdragonsbreath.desc=This flask contains an unusual c items.potions.exotic.potionofearthenarmor.name=potion of earthen armor items.potions.exotic.potionofearthenarmor.desc=Rather than paralyze, this liquid has a hardening effect on the skin which will turn it into temporary natural armor. -items.potions.exotic.potionofholyfuror.name=potion of holy furor -items.potions.exotic.potionofholyfuror.desc=The power of holy energy reduced to liquid form, this draught will bless you for an extended period of time. +items.potions.exotic.potionofdivineinspiration.name=potion of divine inspiration +items.potions.exotic.potionofdivineinspiration.no_more_points=You can't gain any more bonus talent points. +items.potions.exotic.potionofdivineinspiration.select_tier=Select a talent tier to gain two bonus points in. You must have unlocked the tier to be able to spend the points. +items.potions.exotic.potionofdivineinspiration.bonus=+2 Talent Points! +items.potions.exotic.potionofdivineinspiration.desc=The power of holy energy reduced to liquid form, this draught will imbue the drinker with divine power, granting them two bonus talent points in a tier of their choosing.\n\nThis potion can only be used once for each talent tier. items.potions.exotic.potionofmagicalsight.name=potion of magical sight items.potions.exotic.potionofmagicalsight.desc=After drinking this, your senses will be briefly heightened to incredible levels, increasing your vision range and allowing you to see through walls! diff --git a/core/src/main/assets/sprites/item_icons.png b/core/src/main/assets/sprites/item_icons.png index a1a06b59f..2f0bfa437 100644 Binary files a/core/src/main/assets/sprites/item_icons.png and b/core/src/main/assets/sprites/item_icons.png differ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java index 8733b58d0..304d39c67 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ShatteredPixelDungeon.java @@ -55,6 +55,9 @@ public class ShatteredPixelDungeon extends Game { com.watabou.utils.Bundle.addAlias( com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfChallenge.class, "com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfConfusion" ); + com.watabou.utils.Bundle.addAlias( + com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.PotionOfDivineInspiration.class, + "com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.PotionOfHolyFuror" ); //v1.0.0 com.watabou.utils.Bundle.addAlias( 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 356a1344b..16d33faa0 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 @@ -92,6 +92,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfExperience; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing; import com.shatteredpixel.shatteredpixeldungeon.items.potions.elixirs.ElixirOfMight; +import com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.PotionOfDivineInspiration; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfAccuracy; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEvasion; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfForce; @@ -343,14 +344,27 @@ public class Hero extends Char { } public int talentPointsAvailable(int tier){ - if (lvl < Talent.tierLevelThresholds[tier] + if (lvl < (Talent.tierLevelThresholds[tier] - 1) || (tier == 3 && subClass == HeroSubClass.NONE) - || (tier == 4 && armorAbility == null)){ + || (tier == 4 && armorAbility == null)) { return 0; } else if (lvl >= Talent.tierLevelThresholds[tier+1]){ - return Talent.tierLevelThresholds[tier+1] - Talent.tierLevelThresholds[tier] - talentPointsSpent(tier); + return Talent.tierLevelThresholds[tier+1] - Talent.tierLevelThresholds[tier] - talentPointsSpent(tier) + bonusTalentPoints(tier); } else { - return 1 + lvl - Talent.tierLevelThresholds[tier] - talentPointsSpent(tier); + return 1 + lvl - Talent.tierLevelThresholds[tier] - talentPointsSpent(tier) + bonusTalentPoints(tier); + } + } + + public int bonusTalentPoints(int tier){ + if (lvl < (Talent.tierLevelThresholds[tier]-1) + || (tier == 3 && subClass == HeroSubClass.NONE) + || (tier == 4 && armorAbility == null)) { + return 0; + } else if (buff(PotionOfDivineInspiration.DivineInspirationTracker.class) != null + && buff(PotionOfDivineInspiration.DivineInspirationTracker.class).isBoosted(tier)) { + return 2; + } else { + return 0; } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/potions/exotic/ExoticPotion.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/potions/exotic/ExoticPotion.java index 17c849c4e..584b5f62c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/potions/exotic/ExoticPotion.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/potions/exotic/ExoticPotion.java @@ -79,8 +79,8 @@ public class ExoticPotion extends Potion { regToExo.put(PotionOfLevitation.class, PotionOfStormClouds.class); exoToReg.put(PotionOfStormClouds.class, PotionOfLevitation.class); - regToExo.put(PotionOfExperience.class, PotionOfHolyFuror.class); - exoToReg.put(PotionOfHolyFuror.class, PotionOfExperience.class); + regToExo.put(PotionOfExperience.class, PotionOfDivineInspiration.class); + exoToReg.put(PotionOfDivineInspiration.class, PotionOfExperience.class); regToExo.put(PotionOfPurity.class, PotionOfCleansing.class); exoToReg.put(PotionOfCleansing.class, PotionOfPurity.class); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/potions/exotic/PotionOfDivineInspiration.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/potions/exotic/PotionOfDivineInspiration.java new file mode 100644 index 000000000..74b9a99ce --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/potions/exotic/PotionOfDivineInspiration.java @@ -0,0 +1,171 @@ +/* + * 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.items.potions.exotic; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; +import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; +import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; +import com.shatteredpixel.shatteredpixeldungeon.ui.StatusPane; +import com.shatteredpixel.shatteredpixeldungeon.ui.TalentsPane; +import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; +import com.shatteredpixel.shatteredpixeldungeon.windows.WndHero; +import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions; +import com.watabou.noosa.audio.Sample; +import com.watabou.utils.Bundle; + +public class PotionOfDivineInspiration extends ExoticPotion { + + { + icon = ItemSpriteSheet.Icons.POTION_DIVINE; + } + + @Override + //need to override drink so that time isn't spent right away + protected void drink(final Hero hero) { + curUser = hero; + curItem = this; + + boolean[] enabled = new boolean[5]; + enabled[1] = enabled[2] = enabled[3] = enabled[4] = true; + + DivineInspirationTracker tracker = hero.buff(DivineInspirationTracker.class); + + if (tracker != null){ + boolean allBoosted = true; + for (int i = 1; i <= 4; i++){ + if (tracker.isBoosted(i)){ + enabled[i] = false; + } else { + allBoosted = false; + } + } + + if (allBoosted){ + GLog.w(Messages.get(this, "no_more_bonus")); + return; + } + } + + if (!isIdentified()) { + curItem.detach(curUser.belongings.backpack); + } + + GameScene.show(new WndOptions( + new ItemSprite(this), + Messages.titleCase(trueName()), + Messages.get(PotionOfDivineInspiration.class, "select_tier"), + Messages.titleCase(Messages.get(TalentsPane.class, "tier", 1)), + Messages.titleCase(Messages.get(TalentsPane.class, "tier", 2)), + Messages.titleCase(Messages.get(TalentsPane.class, "tier", 3)), + Messages.titleCase(Messages.get(TalentsPane.class, "tier", 4)) + ){ + @Override + protected boolean enabled(int index) { + return enabled[index+1]; + } + + @Override + protected void onSelect(int index) { + super.onSelect(index); + + if (index != -1){ + Buff.affect(curUser, DivineInspirationTracker.class).setBoosted(index+1); + + if (isIdentified()) { + curItem.detach(curUser.belongings.backpack); + } + + identify(); + curUser.busy(); + curUser.sprite.operate(curUser.pos); + + curUser.spendAndNext(1f); + + boolean unspentTalents = false; + for (int i = 1; i <= Dungeon.hero.talents.size(); i++){ + if (Dungeon.hero.talentPointsAvailable(i) > 0){ + unspentTalents = true; + break; + } + } + if (unspentTalents){ + StatusPane.talentBlink = 10f; + WndHero.lastIdx = 1; + } + + GameScene.showlevelUpStars(); + + Sample.INSTANCE.play( Assets.Sounds.DRINK ); + Sample.INSTANCE.playDelayed(Assets.Sounds.LEVELUP, 0.3f, 0.7f, 1.2f); + Sample.INSTANCE.playDelayed(Assets.Sounds.LEVELUP, 0.6f, 0.7f, 1.2f); + GLog.p(Messages.get(PotionOfDivineInspiration.class, "bonus")); + + } + } + + @Override + public void onBackPressed() { + //do nothing, prevents accidentally closing + } + }); + + } + + public static class DivineInspirationTracker extends Buff { + + { + type = buffType.POSITIVE; + revivePersists = true; + } + + private boolean[] boostedTiers = new boolean[5]; + + private static final String BOOSTED_TIERS = "boosted_tiers"; + + @Override + public void storeInBundle(Bundle bundle) { + super.storeInBundle(bundle); + bundle.put(BOOSTED_TIERS, boostedTiers); + } + + @Override + public void restoreFromBundle(Bundle bundle) { + super.restoreFromBundle(bundle); + boostedTiers = bundle.getBooleanArray(BOOSTED_TIERS); + } + + public void setBoosted( int tier ){ + boostedTiers[tier] = true; + } + + public boolean isBoosted( int tier ){ + return boostedTiers[tier]; + } + + } + +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/potions/exotic/PotionOfHolyFuror.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/potions/exotic/PotionOfHolyFuror.java deleted file mode 100644 index 81ab01a00..000000000 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/potions/exotic/PotionOfHolyFuror.java +++ /dev/null @@ -1,41 +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.items.potions.exotic; - -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Bless; -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; -import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; -import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; - -public class PotionOfHolyFuror extends ExoticPotion { - - { - icon = ItemSpriteSheet.Icons.POTION_HOLYFUROR; - } - - @Override - public void apply( Hero hero ) { - identify(); - Buff.prolong(hero, Bless.class, Bless.DURATION*4f); - } - -} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java index 4b4a6fad1..f44ad1e64 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/scenes/GameScene.java @@ -963,6 +963,10 @@ public class GameScene extends PixelScene { public static void flashForDocument( String page ){ if (scene != null) scene.pane.flashForPage( page ); } + + public static void showlevelUpStars(){ + if (scene != null) scene.pane.showStarParticles(); + } public static void updateKeyDisplay(){ if (scene != null) scene.pane.updateKeys(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java index b2064ecdd..49ebab521 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/sprites/ItemSpriteSheet.java @@ -792,7 +792,7 @@ public class ItemSpriteSheet { assignIconRect( SCROLL_CHALLENGE, 7, 7 ); assignIconRect( SCROLL_PSIBLAST, 5, 6 ); assignIconRect( SCROLL_DREAD, 5, 7 ); - assignIconRect( SCROLL_POLYMORPH, 7, 6 ); + assignIconRect( SCROLL_POLYMORPH, 7, 7 ); } //16 free slots @@ -837,7 +837,7 @@ public class ItemSpriteSheet { public static final int POTION_STRMCLOUD= EXOTIC_POTIONS+8; public static final int POTION_EARTHARMR= EXOTIC_POTIONS+9; public static final int POTION_CLEANSE = EXOTIC_POTIONS+10; - public static final int POTION_HOLYFUROR= EXOTIC_POTIONS+11; + public static final int POTION_DIVINE = EXOTIC_POTIONS+11; static { assignIconRect( POTION_ARENSURGE, 7, 7 ); assignIconRect( POTION_SHIELDING, 6, 6 ); @@ -850,7 +850,7 @@ public class ItemSpriteSheet { assignIconRect( POTION_STRMCLOUD, 7, 7 ); assignIconRect( POTION_EARTHARMR, 6, 6 ); assignIconRect( POTION_CLEANSE, 7, 7 ); - assignIconRect( POTION_HOLYFUROR, 5, 7 ); + assignIconRect( POTION_DIVINE, 7, 7 ); } //16 free slots diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/StatusPane.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/StatusPane.java index 53b07abe9..0f247f3b1 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/StatusPane.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/StatusPane.java @@ -241,10 +241,7 @@ public class StatusPane extends Component { if (Dungeon.hero.lvl != lastLvl) { if (lastLvl != -1) { - Emitter emitter = (Emitter)recycle( Emitter.class ); - emitter.revive(); - emitter.pos( 27, 27 ); - emitter.burst( Speck.factory( Speck.STAR ), 12 ); + showStarParticles(); } lastLvl = Dungeon.hero.lvl; @@ -262,6 +259,13 @@ public class StatusPane extends Component { } } + public void showStarParticles(){ + Emitter emitter = (Emitter)recycle( Emitter.class ); + emitter.revive(); + emitter.pos( 27, 27 ); + emitter.burst( Speck.factory( Speck.STAR ), 12 ); + } + public void pickup( Item item, int cell) { pickedUp.reset( item, cell, diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/TalentsPane.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/TalentsPane.java index abed88d74..ff5adcc14 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/TalentsPane.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/TalentsPane.java @@ -193,7 +193,7 @@ public class TalentsPane extends ScrollPane { stars.clear(); } - int totStars = Talent.tierLevelThresholds[tier+1] - Talent.tierLevelThresholds[tier]; + int totStars = Talent.tierLevelThresholds[tier+1] - Talent.tierLevelThresholds[tier] + Dungeon.hero.bonusTalentPoints(tier); int openStars = Dungeon.hero.talentPointsAvailable(tier); int usedStars = Dungeon.hero.talentPointsSpent(tier); for (int i = 0; i < totStars; i++){ @@ -212,16 +212,27 @@ public class TalentsPane extends ScrollPane { protected void layout() { super.layout(); + int regStars = Talent.tierLevelThresholds[tier+1] - Talent.tierLevelThresholds[tier]; + float titleWidth = title.width(); - titleWidth += 2 + stars.size()*6; + titleWidth += 2 + Math.min(stars.size(), regStars)*6; title.setPos(x + (width - titleWidth)/2f, y); float left = title.right() + 2; + + float starTop = title.top(); + if (regStars < stars.size()) starTop -= 2; + for (Image star : stars){ star.x = left; - star.y = title.top(); + star.y = starTop; PixelScene.align(star); left += 6; + regStars--; + if (regStars == 0){ + starTop += 6; + left = title.right() + 2; + } } float gap = (width - buttons.size()*TalentButton.WIDTH)/(buttons.size()+1);