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 501dc3260..42f6d903d 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 @@ -30,6 +30,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.HolyTome; import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand; import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.ui.HeroIcon; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.watabou.noosa.audio.Sample; import com.watabou.utils.Callback; @@ -37,6 +38,13 @@ import com.watabou.utils.Random; public class GuidingLight extends ClericSpell { + public static GuidingLight INSTANCE = new GuidingLight(); + + @Override + public int icon() { + return HeroIcon.ELEMENTAL_BLAST; //TODO unique icon + } + @Override public String targetingPrompt() { return Messages.get(this, "prompt"); 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 a0e4ce4bd..9ed2e08ea 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 @@ -24,13 +24,15 @@ package com.shatteredpixel.shatteredpixeldungeon.items.artifacts; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicImmune; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; -import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.GuidingLight; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.ClericSpell; import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEnergy; import com.shatteredpixel.shatteredpixeldungeon.journal.Catalog; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; +import com.shatteredpixel.shatteredpixeldungeon.windows.WndClericSpells; import java.util.ArrayList; @@ -74,21 +76,22 @@ public class HolyTome extends Artifact { if (hero.buff(MagicImmune.class) != null) return; if (action.equals(AC_CAST)) { - usesTargeting = false; if (!isEquipped(hero)) GLog.i(Messages.get(Artifact.class, "need_to_equip")); else if (charge == 0) GLog.i(Messages.get(this, "no_charge")); else { - //TODO need to flow into spell selection and not just auto-cast guiding light - usesTargeting = true; - new GuidingLight().use(this, hero); + GameScene.show(new WndClericSpells(this, hero, false)); } } } + public boolean canCast( Hero hero, ClericSpell spell ){ + return (charge >= spell.chargeUse(hero)); + } + public void spendCharge( float chargesSpent ){ partialCharge -= chargesSpent; while (partialCharge < 0){ 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 80cfe19d2..20be7d726 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/HeroIcon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/HeroIcon.java @@ -24,6 +24,7 @@ package com.shatteredpixel.shatteredpixeldungeon.ui; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.ClericSpell; import com.watabou.noosa.Image; import com.watabou.noosa.TextureFilm; @@ -75,6 +76,9 @@ public class HeroIcon extends Image { public static final int WEAPON_SWAP = 37; public static final int MONK_ABILITIES = 38; + //cleric spells + + public HeroIcon(HeroSubClass subCls){ super( Assets.Interfaces.HERO_ICONS ); if (film == null){ @@ -99,4 +103,12 @@ public class HeroIcon extends Image { frame(film.get(action.actionIcon())); } + public HeroIcon(ClericSpell spell){ + super( Assets.Interfaces.HERO_ICONS ); + if (film == null){ + film = new TextureFilm(texture, SIZE, SIZE); + } + frame(film.get(spell.icon())); + } + } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndClericSpells.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndClericSpells.java new file mode 100644 index 000000000..38dbd0732 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndClericSpells.java @@ -0,0 +1,112 @@ +/* + * Pixel Dungeon + * Copyright (C) 2012-2015 Oleg Dolya + * + * Shattered Pixel Dungeon + * Copyright (C) 2014-2024 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.windows; + +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.items.artifacts.HolyTome; +import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; +import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene; +import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; +import com.shatteredpixel.shatteredpixeldungeon.ui.HeroIcon; +import com.shatteredpixel.shatteredpixeldungeon.ui.IconButton; +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 java.util.ArrayList; + +public class WndClericSpells extends Window { + + protected static final int WIDTH = 120; + + public WndClericSpells(HolyTome tome, Hero cleric, boolean info){ + + IconTitle title = new IconTitle(new ItemSprite(tome), info ? "Spell Info" : "Cast A Spell"); + + title.setRect(0, 0, WIDTH, 0); + add(title); + + IconButton btnInfo = new IconButton(Icons.INFO.get()){ + @Override + protected void onClick() { + GameScene.show(new WndClericSpells(tome, cleric, !info)); + hide(); + } + }; + btnInfo.setRect(WIDTH-16, 0, 16, 16); + 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); + msg.maxWidth(WIDTH); + msg.setPos(0, title.bottom()+4); + add(msg); + + //TODO build spell list + ArrayList spells = new ArrayList<>(); + spells.add(GuidingLight.INSTANCE); + + 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); + } + add(spellBtn); + spellBtns.add(spellBtn); + } + + //TODO rows? + int left = 0; + for (IconButton btn : spellBtns){ + btn.setRect(left, msg.bottom()+4, 20, 20); + left += btn.width()+4; + } + + resize(WIDTH, (int)spellBtns.get(0).bottom()); + + } + + //TODO we probably want to offset this window for mobile so it appears closer to quickslots + +}