v3.0.0: added 'quick cast' functionality for cleric spells
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.6 KiB |
@@ -343,6 +343,7 @@ items.artifacts.etherealchains$chainsrecharge.levelup=Your chains grow stronger!
|
|||||||
items.artifacts.holytome.name=holy tome
|
items.artifacts.holytome.name=holy tome
|
||||||
items.artifacts.holytome.ac_cast=CAST
|
items.artifacts.holytome.ac_cast=CAST
|
||||||
items.artifacts.holytome.no_charge=Your tome is out of charge. Gain exp to recharge it.
|
items.artifacts.holytome.no_charge=Your tome is out of charge. Gain exp to recharge it.
|
||||||
|
items.artifacts.holytome.no_spell=You're not able to cast that spell right now.
|
||||||
items.artifacts.holytome.levelup=Your tome grows stronger!
|
items.artifacts.holytome.levelup=Your tome grows stronger!
|
||||||
items.artifacts.holytome.desc=A holy tome that acts as a focus for the Cleric's divine magic. Using the tome lets the Cleric cast a variety of magical spells.\n\nThe tome will steadily get more powerful as the Cleric uses it, and it will recharge as the Cleric gains experience points when defeating enemies.
|
items.artifacts.holytome.desc=A holy tome that acts as a focus for the Cleric's divine magic. Using the tome lets the Cleric cast a variety of magical spells.\n\nThe tome will steadily get more powerful as the Cleric uses it, and it will recharge as the Cleric gains experience points when defeating enemies.
|
||||||
|
|
||||||
|
|||||||
@@ -41,8 +41,12 @@ windows.wndclass.mastery=Mastery
|
|||||||
|
|
||||||
windows.wndclericspells.cast_title=cast a spell
|
windows.wndclericspells.cast_title=cast a spell
|
||||||
windows.wndclericspells.info_title=spell info
|
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.cast_desc_desktop=Select a spell to cast it, right click for info or to set a spell to quick cast.
|
||||||
|
windows.wndclericspells.cast_desc_mobile=Select a spell to cast it, long press to set a spell to quick cast, 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.wndclericspells.info_desc=Select a spell to learn about it, or press the info button to switch to cast mode.
|
||||||
|
windows.wndclericspells.cast=Cast
|
||||||
|
windows.wndclericspells.info=Info
|
||||||
|
windows.wndclericspells.quick_cast=Quick Cast
|
||||||
|
|
||||||
windows.wndcombo.title=choose a combo move
|
windows.wndcombo.title=choose a combo move
|
||||||
windows.wndcombo.combo_req=(%d combo)
|
windows.wndcombo.combo_req=(%d combo)
|
||||||
|
|||||||
+14
-1
@@ -119,6 +119,19 @@ public abstract class ClericSpell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return spells;
|
return spells;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
public static ArrayList<ClericSpell> getAllSpells() {
|
||||||
|
ArrayList<ClericSpell> spells = new ArrayList<>();
|
||||||
|
spells.add(GuidingLight.INSTANCE);
|
||||||
|
spells.add(HolyWeapon.INSTANCE);
|
||||||
|
spells.add(HolyWard.INSTANCE);
|
||||||
|
spells.add(ShieldOfLight.INSTANCE);
|
||||||
|
spells.add(DetectCurse.INSTANCE);
|
||||||
|
spells.add(Sunray.INSTANCE);
|
||||||
|
spells.add(RecallGlyph.INSTANCE);
|
||||||
|
spells.add(DivineSense.INSTANCE);
|
||||||
|
spells.add(HolyLance.INSTANCE);
|
||||||
|
return spells;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -86,7 +86,9 @@ public class GuidingLight extends TargetedClericSpell {
|
|||||||
hero.next();
|
hero.next();
|
||||||
|
|
||||||
onSpellCast(tome, hero);
|
onSpellCast(tome, hero);
|
||||||
Buff.affect(hero, GuidingLightPriestCooldown.class, 100f);
|
if (hero.subClass == HeroSubClass.PRIEST) {
|
||||||
|
Buff.affect(hero, GuidingLightPriestCooldown.class, 100f);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
+90
-1
@@ -26,6 +26,8 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicImmune;
|
|||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.ClericSpell;
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.ClericSpell;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.DetectCurse;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.TargetedClericSpell;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag;
|
import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEnergy;
|
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEnergy;
|
||||||
@@ -33,8 +35,12 @@ import com.shatteredpixel.shatteredpixeldungeon.journal.Catalog;
|
|||||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.ui.ActionIndicator;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.ui.HeroIcon;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.windows.WndClericSpells;
|
import com.shatteredpixel.shatteredpixeldungeon.windows.WndClericSpells;
|
||||||
|
import com.watabou.utils.Bundle;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@@ -203,7 +209,45 @@ public class HolyTome extends Artifact {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TomeRecharge extends ArtifactBuff {
|
private ClericSpell quickSpell = null;
|
||||||
|
|
||||||
|
public void setQuickSpell(ClericSpell spell){
|
||||||
|
quickSpell = spell;
|
||||||
|
if (passiveBuff != null){
|
||||||
|
ActionIndicator.setAction((ActionIndicator.Action) passiveBuff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String QUICK_CLS = "quick_cls";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storeInBundle(Bundle bundle) {
|
||||||
|
super.storeInBundle(bundle);
|
||||||
|
if (quickSpell != null) {
|
||||||
|
bundle.put(QUICK_CLS, quickSpell.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void restoreFromBundle(Bundle bundle) {
|
||||||
|
super.restoreFromBundle(bundle);
|
||||||
|
if (bundle.contains(QUICK_CLS)){
|
||||||
|
Class quickCls = bundle.getClass(QUICK_CLS);
|
||||||
|
for (ClericSpell spell : ClericSpell.getAllSpells()){
|
||||||
|
if (spell.getClass() == quickCls){
|
||||||
|
quickSpell = spell;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TomeRecharge extends ArtifactBuff implements ActionIndicator.Action {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fx(boolean on) {
|
||||||
|
if (on && quickSpell != null) ActionIndicator.setAction(this);
|
||||||
|
else ActionIndicator.clearAction(this);
|
||||||
|
}
|
||||||
|
|
||||||
public void gainCharge(float levelPortion) {
|
public void gainCharge(float levelPortion) {
|
||||||
if (cursed || target.buff(MagicImmune.class) != null) return;
|
if (cursed || target.buff(MagicImmune.class) != null) return;
|
||||||
@@ -242,6 +286,51 @@ public class HolyTome extends Artifact {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String actionName() {
|
||||||
|
return quickSpell.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int actionIcon() {
|
||||||
|
return quickSpell.icon() + HeroIcon.SPELL_ACTION_OFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int indicatorColor() {
|
||||||
|
if (quickSpell == DetectCurse.INSTANCE){
|
||||||
|
return 0x00A0FF;
|
||||||
|
} else {
|
||||||
|
return 0x002157;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doAction() {
|
||||||
|
if (!canCast(Dungeon.hero, quickSpell)){
|
||||||
|
GLog.w(Messages.get(HolyTome.this, "no_spell"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO this is all pretty akward, might be better to just add autotarget functionality to the indicator
|
||||||
|
if (QuickSlotButton.targetingSlot != -1 &&
|
||||||
|
Dungeon.quickslot.getItem(QuickSlotButton.targetingSlot) == HolyTome.this) {
|
||||||
|
int cell = QuickSlotButton.autoAim(QuickSlotButton.lastTarget, HolyTome.this);
|
||||||
|
|
||||||
|
if (cell != -1){
|
||||||
|
GameScene.handleCell(cell);
|
||||||
|
} else {
|
||||||
|
//couldn't auto-aim, just target the position and hope for the best.
|
||||||
|
GameScene.handleCell( QuickSlotButton.lastTarget.pos );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quickSpell.onCast(HolyTome.this, Dungeon.hero);
|
||||||
|
|
||||||
|
if (quickSpell instanceof TargetedClericSpell && Dungeon.quickslot.contains(HolyTome.this)){
|
||||||
|
QuickSlotButton.useTargeting(Dungeon.quickslot.getSlot(HolyTome.this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,15 +83,17 @@ public class HeroIcon extends Image {
|
|||||||
public static final int RECALL_GLYPH = 47;
|
public static final int RECALL_GLYPH = 47;
|
||||||
public static final int HOLY_LANCE = 48;
|
public static final int HOLY_LANCE = 48;
|
||||||
|
|
||||||
//action indicator visuals
|
//all cleric spells have a separate icon with no background for the action indicator
|
||||||
public static final int BERSERK = 80;
|
public static final int SPELL_ACTION_OFFSET = 32;
|
||||||
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;
|
|
||||||
|
|
||||||
|
//action indicator visuals
|
||||||
|
public static final int BERSERK = 104;
|
||||||
|
public static final int COMBO = 105;
|
||||||
|
public static final int PREPARATION = 106;
|
||||||
|
public static final int MOMENTUM = 107;
|
||||||
|
public static final int SNIPERS_MARK = 108;
|
||||||
|
public static final int WEAPON_SWAP = 109;
|
||||||
|
public static final int MONK_ABILITIES = 110;
|
||||||
|
|
||||||
public HeroIcon(HeroSubClass subCls){
|
public HeroIcon(HeroSubClass subCls){
|
||||||
super( Assets.Interfaces.HERO_ICONS );
|
super( Assets.Interfaces.HERO_ICONS );
|
||||||
|
|||||||
+78
-8
@@ -38,9 +38,15 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.IconButton;
|
|||||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Icons;
|
import com.shatteredpixel.shatteredpixeldungeon.ui.Icons;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton;
|
import com.shatteredpixel.shatteredpixeldungeon.ui.QuickSlotButton;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextBlock;
|
import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextBlock;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.ui.RightClickMenu;
|
||||||
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
|
import com.shatteredpixel.shatteredpixeldungeon.ui.Window;
|
||||||
|
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||||
|
import com.watabou.input.PointerEvent;
|
||||||
import com.watabou.noosa.ColorBlock;
|
import com.watabou.noosa.ColorBlock;
|
||||||
|
import com.watabou.noosa.Image;
|
||||||
import com.watabou.noosa.NinePatch;
|
import com.watabou.noosa.NinePatch;
|
||||||
|
import com.watabou.utils.DeviceCompat;
|
||||||
|
import com.watabou.utils.PointF;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@@ -67,8 +73,14 @@ public class WndClericSpells extends Window {
|
|||||||
btnInfo.setRect(WIDTH-16, 0, 16, 16);
|
btnInfo.setRect(WIDTH-16, 0, 16, 16);
|
||||||
add(btnInfo);
|
add(btnInfo);
|
||||||
|
|
||||||
//TODO we might want to intercept quickslot hotkeys and auto-cast the last spell if relevant
|
RenderedTextBlock msg;
|
||||||
RenderedTextBlock msg = PixelScene.renderTextBlock( Messages.get( this, info ? "info_desc" : "cast_desc"), 6);
|
if (info){
|
||||||
|
msg = PixelScene.renderTextBlock( Messages.get( this, "info_desc"), 6);
|
||||||
|
} else if (DeviceCompat.isDesktop()){
|
||||||
|
msg = PixelScene.renderTextBlock( Messages.get( this, "cast_desc_desktop"), 6);
|
||||||
|
} else {
|
||||||
|
msg = PixelScene.renderTextBlock( Messages.get( this, "cast_desc_mobile"), 6);
|
||||||
|
}
|
||||||
msg.maxWidth(WIDTH);
|
msg.maxWidth(WIDTH);
|
||||||
msg.setPos(0, title.bottom()+4);
|
msg.setPos(0, title.bottom()+4);
|
||||||
add(msg);
|
add(msg);
|
||||||
@@ -127,8 +139,8 @@ public class WndClericSpells extends Window {
|
|||||||
this.tome = tome;
|
this.tome = tome;
|
||||||
this.info = info;
|
this.info = info;
|
||||||
|
|
||||||
if (!info && !tome.canCast(Dungeon.hero, spell)){
|
if (!tome.canCast(Dungeon.hero, spell)){
|
||||||
enable(false);
|
icon.alpha( 0.3f );
|
||||||
}
|
}
|
||||||
|
|
||||||
bg = Chrome.get(Chrome.Type.TOAST);
|
bg = Chrome.get(Chrome.Type.TOAST);
|
||||||
@@ -152,15 +164,73 @@ public class WndClericSpells extends Window {
|
|||||||
GameScene.show(new WndTitledMessage(new HeroIcon(spell), Messages.titleCase(spell.name()), spell.desc()));
|
GameScene.show(new WndTitledMessage(new HeroIcon(spell), Messages.titleCase(spell.name()), spell.desc()));
|
||||||
} else {
|
} else {
|
||||||
hide();
|
hide();
|
||||||
spell.onCast(tome, Dungeon.hero);
|
|
||||||
|
|
||||||
//TODO, probably need targeting logic here
|
|
||||||
if (spell instanceof TargetedClericSpell && Dungeon.quickslot.contains(tome)){
|
if(!spell.canCast(Dungeon.hero)){
|
||||||
QuickSlotButton.useTargeting(Dungeon.quickslot.getSlot(tome));
|
GLog.w(Messages.get(HolyTome.class, "no_spell"));
|
||||||
|
} else {
|
||||||
|
spell.onCast(tome, Dungeon.hero);
|
||||||
|
|
||||||
|
//TODO, probably need targeting logic here
|
||||||
|
if (spell instanceof TargetedClericSpell && Dungeon.quickslot.contains(tome)){
|
||||||
|
QuickSlotButton.useTargeting(Dungeon.quickslot.getSlot(tome));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onLongClick() {
|
||||||
|
hide();
|
||||||
|
tome.setQuickSpell(spell);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRightClick() {
|
||||||
|
super.onRightClick();
|
||||||
|
RightClickMenu r = new RightClickMenu(new Image(icon),
|
||||||
|
Messages.titleCase(spell.name()),
|
||||||
|
Messages.get(WndClericSpells.class, "cast"),
|
||||||
|
Messages.get(WndClericSpells.class, "info"),
|
||||||
|
Messages.get(WndClericSpells.class, "quick_cast")){
|
||||||
|
@Override
|
||||||
|
public void onSelect(int index) {
|
||||||
|
switch (index){
|
||||||
|
default:
|
||||||
|
//do nothing
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
hide();
|
||||||
|
if(!spell.canCast(Dungeon.hero)){
|
||||||
|
GLog.w(Messages.get(HolyTome.class, "no_spell"));
|
||||||
|
} else {
|
||||||
|
spell.onCast(tome, Dungeon.hero);
|
||||||
|
|
||||||
|
//TODO, probably need targeting logic here
|
||||||
|
if (spell instanceof TargetedClericSpell && Dungeon.quickslot.contains(tome)){
|
||||||
|
QuickSlotButton.useTargeting(Dungeon.quickslot.getSlot(tome));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
GameScene.show(new WndTitledMessage(new HeroIcon(spell), Messages.titleCase(spell.name()), spell.desc()));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
hide();
|
||||||
|
tome.setQuickSpell(spell);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
parent.addToFront(r);
|
||||||
|
r.camera = camera();
|
||||||
|
PointF mousePos = PointerEvent.currentHoverPos();
|
||||||
|
mousePos = camera.screenToCamera((int)mousePos.x, (int)mousePos.y);
|
||||||
|
r.setPos(mousePos.x-3, mousePos.y-3);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String hoverText() {
|
protected String hoverText() {
|
||||||
return "_" + Messages.titleCase(spell.name()) + "_\n" + spell.shortDesc();
|
return "_" + Messages.titleCase(spell.name()) + "_\n" + spell.shortDesc();
|
||||||
|
|||||||
Reference in New Issue
Block a user