diff --git a/core/src/main/assets/interfaces/buffs.png b/core/src/main/assets/interfaces/buffs.png index 64f8054cb..864d610c1 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/hero_icons.png b/core/src/main/assets/interfaces/hero_icons.png index 4a7c0525f..669c6c3c5 100644 Binary files a/core/src/main/assets/interfaces/hero_icons.png and b/core/src/main/assets/interfaces/hero_icons.png differ diff --git a/core/src/main/assets/interfaces/large_buffs.png b/core/src/main/assets/interfaces/large_buffs.png index 4253c026e..c5f13c099 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 2cee17539..2edc8935d 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 03c833224..5ffbb1a32 100644 --- a/core/src/main/assets/messages/actors/actors.properties +++ b/core/src/main/assets/messages/actors/actors.properties @@ -535,17 +535,21 @@ actors.hero.abilities.ratmogrify$transmograt.rankings_desc=Slain by: ratmogrifie ##Cleric Spells actors.hero.spells.guidinglight.name=guiding light actors.hero.spells.guidinglight.prompt=choose a target -actors.hero.spells.guidinglight.desc=TODO, just deals damage atm +actors.hero.spells.guidinglight.desc=The Cleric files a bolt of magical energy which strikes a target, dealing 2-6 damage and illuminating them. The next melee attack made against an illuminated enemy is guaranteed to hit them.\n\nThis spell costs 1 charge. actors.hero.spells.holyward.name=holy ward actors.hero.spells.holyward.glyph_name=%s of light actors.hero.spells.holyward.glyph_desc=This glyph slightly increases the amount of damage armor can block. -actors.hero.spells.holyward.desc=TODO, temp armor buff +actors.hero.spells.holyward.desc=The Cleric imbues their worn armor with glyphs of holy light, increasing the armor's damage blocking by 1.\n\nThis glyph lasts for 50 turns, and will override any beneficial glyph the armor has for the duration.\n\nThis spell costs 1 charge. +actors.hero.spells.holyward$holyarmbuff.name=holy ward +actors.hero.spells.holyward$holyarmbuff.desc=The Cleric has imbued their worn armor with holy energy, temporarily overriding any existing glyph and causing the armor to block an extra 1 point of damage.\n\nTurn renaming: %s. actors.hero.spells.holyweapon.name=holy weapon actors.hero.spells.holyweapon.ench_name=holy %s actors.hero.spells.holyweapon.ench_desc=Enemies struck by a holy weapon will take extra magical damage. -actors.hero.spells.holyweapon.desc=TODO, temp melee weapon buff +actors.hero.spells.holyweapon.desc=The Cleric enchants their worn weapon with holy energy, causing the weapon to deal an additional 2 magical damage any time they strike an enemy with it.\n\nThis enchantment lasts for 50 turns, and will override any beneficial enchantment the weapon has for the duration.\n\nThis spell costs 2 charges. +actors.hero.spells.holyweapon$holywepbuff.name=holy weapon +actors.hero.spells.holyweapon$holywepbuff.desc=The Cleric has imbued their worn weapon with holy energy, temporarily overriding any existing enchantment and causing the weapon to deal an extra 2 magical damage on each attack.\n\nTurn renaming: %s. diff --git a/core/src/main/assets/messages/windows/windows.properties b/core/src/main/assets/messages/windows/windows.properties index 26cfe8dad..f39058bf7 100644 --- a/core/src/main/assets/messages/windows/windows.properties +++ b/core/src/main/assets/messages/windows/windows.properties @@ -39,6 +39,11 @@ windows.wndchoosesubclass.no=No, I'll decide later. windows.wndclass.mastery=Mastery +windows.wndclericspells.cast_title=cast a spell +windows.wndclericspells.info_title=spell info +windows.wndclericspells.cast_desc=Select a spell to cast it, or press the info button to switch to info mode. +windows.wndclericspells.info_desc=Select a spell to learn about it, or press the info button to switch to cast mode. + windows.wndcombo.title=choose a combo move windows.wndcombo.combo_req=(%d combo) diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/GuidingLight.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/GuidingLight.java index 1b8f7e2a7..7ad22b94c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/GuidingLight.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/GuidingLight.java @@ -44,7 +44,7 @@ public class GuidingLight extends ClericSpell { @Override public int icon() { - return HeroIcon.ELEMENTAL_BLAST; //TODO unique icon + return HeroIcon.GUIDING_LIGHT; } @Override @@ -81,7 +81,7 @@ public class GuidingLight extends ClericSpell { } } - tome.spendCharge( 1f ); + tome.spendCharge( chargeUse(hero) ); hero.spend( 1f ); hero.next(); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/HolyWard.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/HolyWard.java index 597d8a942..65ae94bd6 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/HolyWard.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/HolyWard.java @@ -37,12 +37,7 @@ public class HolyWard extends ClericSpell { @Override public int icon() { - return HeroIcon.ENDURE; //TODO unique icon - } - - @Override - public float chargeUse(Hero hero) { - return 1; + return HeroIcon.HOLY_WARD; } @Override @@ -52,7 +47,7 @@ public class HolyWard extends ClericSpell { Item.updateQuickslot(); Sample.INSTANCE.play(Assets.Sounds.READ); - tome.spendCharge( 1f ); + tome.spendCharge( chargeUse(hero) ); hero.sprite.operate(hero.pos); hero.spend( 1f ); hero.next(); @@ -60,9 +55,20 @@ public class HolyWard extends ClericSpell { public static class HolyArmBuff extends FlavourBuff { + public static final float DURATION = 50f; + + { + type = buffType.POSITIVE; + } + @Override public int icon() { - return BuffIndicator.ARMOR; + return BuffIndicator.HOLY_ARMOR; + } + + @Override + public float iconFadePercent() { + return Math.max(0, (DURATION - visualcooldown()) / DURATION); } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/HolyWeapon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/HolyWeapon.java index 3d42a1010..13a89e7be 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/HolyWeapon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/HolyWeapon.java @@ -37,7 +37,7 @@ public class HolyWeapon extends ClericSpell { @Override public int icon() { - return HeroIcon.ELEMENTAL_STRIKE; //TODO unique icon + return HeroIcon.HOLY_WEAPON; } @Override @@ -52,7 +52,7 @@ public class HolyWeapon extends ClericSpell { Item.updateQuickslot(); Sample.INSTANCE.play(Assets.Sounds.READ); - tome.spendCharge( 2f ); + tome.spendCharge( chargeUse(hero) ); hero.sprite.operate(hero.pos); hero.spend( 1f ); hero.next(); @@ -60,9 +60,20 @@ public class HolyWeapon extends ClericSpell { public static class HolyWepBuff extends FlavourBuff { + public static final float DURATION = 50f; + + { + type = buffType.POSITIVE; + } + @Override public int icon() { - return BuffIndicator.WEAPON; + return BuffIndicator.HOLY_WEAPON; + } + + @Override + public float iconFadePercent() { + return Math.max(0, (DURATION - visualcooldown()) / DURATION); } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/HolyTome.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/HolyTome.java index 9ed2e08ea..0bf9bdfe6 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/HolyTome.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/HolyTome.java @@ -61,8 +61,7 @@ public class HolyTome extends Artifact { ArrayList actions = super.actions( hero ); if (isEquipped( hero ) && !cursed - && hero.buff(MagicImmune.class) == null - && charge > 0) { + && hero.buff(MagicImmune.class) == null) { actions.add(AC_CAST); } return actions; @@ -78,7 +77,6 @@ public class HolyTome extends Artifact { if (action.equals(AC_CAST)) { if (!isEquipped(hero)) GLog.i(Messages.get(Artifact.class, "need_to_equip")); - else if (charge == 0) GLog.i(Messages.get(this, "no_charge")); else { GameScene.show(new WndClericSpells(this, hero, false)); 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 ef7bdebc5..3b9162cd5 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java @@ -122,6 +122,8 @@ public class BuffIndicator extends Component { public static final int DAZE = 70; public static final int DISGUISE = 71; public static final int WAND = 72; + public static final int HOLY_WEAPON = 73; + public static final int HOLY_ARMOR = 74; public static final int SIZE_SMALL = 7; public static final int SIZE_LARGE = 16; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/HeroIcon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/HeroIcon.java index 20be7d726..d83de5c13 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/HeroIcon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/HeroIcon.java @@ -67,16 +67,19 @@ public class HeroIcon extends Image { public static final int FEINT = 30; public static final int RATMOGRIFY = 31; - //action indicator visuals - public static final int BERSERK = 32; - public static final int COMBO = 33; - public static final int PREPARATION = 34; - public static final int MOMENTUM = 35; - public static final int SNIPERS_MARK = 36; - public static final int WEAPON_SWAP = 37; - public static final int MONK_ABILITIES = 38; - //cleric spells + public static final int GUIDING_LIGHT = 40; + public static final int HOLY_WEAPON = 41; + public static final int HOLY_WARD = 42; + + //action indicator visuals + public static final int BERSERK = 80; + public static final int COMBO = 81; + public static final int PREPARATION = 82; + public static final int MOMENTUM = 83; + public static final int SNIPERS_MARK = 84; + public static final int WEAPON_SWAP = 85; + public static final int MONK_ABILITIES = 86; public HeroIcon(HeroSubClass subCls){ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndClericSpells.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndClericSpells.java index 5c2393223..bb173aafc 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndClericSpells.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndClericSpells.java @@ -21,14 +21,15 @@ package com.shatteredpixel.shatteredpixeldungeon.windows; +import com.shatteredpixel.shatteredpixeldungeon.Chrome; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; -import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.ClericSpell; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.GuidingLight; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.HolyWard; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.HolyWeapon; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.HolyTome; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; @@ -38,6 +39,7 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.Icons; import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton; import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextBlock; import com.shatteredpixel.shatteredpixeldungeon.ui.Window; +import com.watabou.noosa.NinePatch; import java.util.ArrayList; @@ -45,9 +47,11 @@ public class WndClericSpells extends Window { protected static final int WIDTH = 120; + public static int BTN_SIZE = 20; + public WndClericSpells(HolyTome tome, Hero cleric, boolean info){ - IconTitle title = new IconTitle(new ItemSprite(tome), info ? "Spell Info" : "Cast A Spell"); + IconTitle title = new IconTitle(new ItemSprite(tome), Messages.titleCase(Messages.get( this, info ? "info_title" : "cast_title"))); title.setRect(0, 0, WIDTH, 0); add(title); @@ -63,7 +67,7 @@ public class WndClericSpells extends Window { add(btnInfo); //TODO we might want to intercept quickslot hotkeys and auto-cast the last spell if relevant - RenderedTextBlock msg = PixelScene.renderTextBlock( info ? "Select a spell to learn about it, or press the info button to switch to cast mode." : "Select a spell to cast it, or press the info button to switch to info mode.", 6); + RenderedTextBlock msg = PixelScene.renderTextBlock( Messages.get( this, info ? "info_desc" : "cast_desc"), 6); msg.maxWidth(WIDTH); msg.setPos(0, title.bottom()+4); add(msg); @@ -77,33 +81,15 @@ public class WndClericSpells extends Window { ArrayList spellBtns = new ArrayList<>(); for (ClericSpell spell : spells){ - IconButton spellBtn = new IconButton(new HeroIcon(spell)){ - @Override - protected void onClick() { - if (info){ - ShatteredPixelDungeon.scene().addToFront(new WndTitledMessage(new HeroIcon(spell), spell.name(), spell.desc())); - } else { - hide(); - spell.use(tome, cleric); - - //TODO, probably need targeting logic here - if (spell.useTargeting() && Dungeon.quickslot.contains(tome)){ - QuickSlotButton.useTargeting(Dungeon.quickslot.getSlot(tome)); - } - } - } - }; - if (!info && !tome.canCast(cleric, spell)){ - spellBtn.enable(false); - } + IconButton spellBtn = new SpellButton(spell, tome, info); add(spellBtn); spellBtns.add(spellBtn); } - //TODO rows? - int left = 0; + //TODO rows? Maybe based on spell tiers? + int left = 2 + (WIDTH-spellBtns.size()*(BTN_SIZE+4))/2; for (IconButton btn : spellBtns){ - btn.setRect(left, msg.bottom()+4, 20, 20); + btn.setRect(left, msg.bottom()+4, BTN_SIZE, BTN_SIZE); left += btn.width()+4; } @@ -113,4 +99,54 @@ public class WndClericSpells extends Window { //TODO we probably want to offset this window for mobile so it appears closer to quickslots + public class SpellButton extends IconButton { + + ClericSpell spell; + HolyTome tome; + boolean info; + + NinePatch bg; + + public SpellButton(ClericSpell spell, HolyTome tome, boolean info){ + super(new HeroIcon(spell)); + + this.spell = spell; + this.tome = tome; + this.info = info; + + if (!info && !tome.canCast(Dungeon.hero, spell)){ + enable(false); + } + + bg = Chrome.get(Chrome.Type.TOAST); + addToBack(bg); + } + + @Override + protected void layout() { + super.layout(); + + if (bg != null) { + bg.size(width, height); + bg.x = x; + bg.y = y; + } + } + + @Override + protected void onClick() { + if (info){ + GameScene.show(new WndTitledMessage(new HeroIcon(spell), Messages.titleCase(spell.name()), spell.desc())); + } else { + hide(); + spell.use(tome, Dungeon.hero); + + //TODO, probably need targeting logic here + if (spell.useTargeting() && Dungeon.quickslot.contains(tome)){ + QuickSlotButton.useTargeting(Dungeon.quickslot.getSlot(tome)); + } + } + } + } + }