v3.0.0: implemented the recall glyph talent/spell for scrolls only
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
@@ -570,6 +570,12 @@ actors.hero.spells.holyweapon.desc=The Cleric enchants their worn weapon with ho
|
||||
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\nTurns renaming: %s.
|
||||
|
||||
actors.hero.spells.recallglyph.name=recall glyph
|
||||
actors.hero.spells.recallglyph.short_desc=Repeats a recently used stone or scroll.
|
||||
actors.hero.spells.recallglyph.desc=The Cleric uses holy magic to replicate and re-cast the effect of a magical glyph found on a runestone or scroll they used in the last %s turns.\n\nRecall Glyph cannot be used to replicate scrolls of upgrade. This spell's charge cost varies based on which item was used recently: 1 for a runestone, 2 for a scroll, 3 for an exotic scroll. This charge cost is also doubled when replicating a scroll of transmutation, or alchemy items that must be crafted using transmutation or upgrade.
|
||||
actors.hero.spells.recallglyph$usedglyphtracker.name=recently used glyph
|
||||
actors.hero.spells.recallglyph$usedglyphtracker.desc=The Cleric has recently used an item that works with the recall glyph spell. The Cleric can cast the spell to repeat the item's effect.\n\nItem Used: %1$s.\n\nTurns Remaining: %2$s.
|
||||
|
||||
actors.hero.spells.shieldoflight.name=shield of light
|
||||
actors.hero.spells.shieldoflight.prompt=Choose a target
|
||||
actors.hero.spells.shieldoflight.short_desc=Grants temporary armor against a target.
|
||||
@@ -1020,12 +1026,12 @@ actors.hero.talent.detect_curse.desc=_+1:_ The Cleric can cast _Detect Curse,_ a
|
||||
actors.hero.talent.searing_light.title=searing light
|
||||
actors.hero.talent.searing_light.desc=_+1:_ Physical attacks on enemies illuminated by _Guiding Light_ deal _+3 damage._\n\n_+2:_ Physical attacks on enemies illuminated by _Guiding Light_ deal _+5 damage._
|
||||
actors.hero.talent.shield_of_light.title=shield of light
|
||||
actors.hero.talent.shield_of_light.desc=_+1:_ The Cleric can cast _Shield of Light,_ a spell that is cast instantly and grants them 2-4 armor against a target for _3 turns_ at the cost of 1 charge.\n\n_+2:_ The Cleric can cast _Shield of Light,_ a spell that is cast instantly and them 2-4 armor against a target for _5 turns_ at the cost of 1 charge.
|
||||
actors.hero.talent.shield_of_light.desc=_+1:_ The Cleric can cast _Shield of Light,_ a spell that is cast instantly and grants them 2-4 armor against a target for _3 turns_ at the cost of 1 charge.\n\n_+2:_ The Cleric can cast _Shield of Light,_ a spell that is cast instantly and grants them 2-4 armor against a target for _5 turns_ at the cost of 1 charge.
|
||||
|
||||
actors.hero.talent.enlightening_meal.title=Enlightening Meal
|
||||
actors.hero.talent.enlightening_meal.desc=_+1:_ Eating food takes the Cleric 1 turn and grants them _1 charge_ on their holy tome.\n\n_+2:_ Eating food takes the Cleric 1 turn and grants them _1.5 charges_ on their holy tome.
|
||||
actors.hero.talent.clerict2b.title=TODO
|
||||
actors.hero.talent.clerict2b.desc=TODO
|
||||
actors.hero.talent.recall_glyph.title=Recall Glyph
|
||||
actors.hero.talent.recall_glyph.desc=_+1:_ The Cleric can cast _Recall Glyph,_ a spell that lets the Cleric repeat the effect of the last runestone or scroll they used within the last _10 turns._\n\n_+2:_ The Cleric can cast _Recall Glyph,_ a spell that lets the Cleric repeat the effect of the last runestone or scroll they used within the last _300 turns._\n\nRecall Glyph cannot be used with scrolls of upgrade. This spell's charge cost varies based on which item was used recently: 1 for a runestone, 2 for a scroll, 3 for an exotic scroll. This charge cost is also doubled when used with a scroll of transmutation, or alchemy items that must be crafted using transmutation or upgrade.
|
||||
actors.hero.talent.sunray.title=Sunray
|
||||
actors.hero.talent.sunray.desc=_+1:_ The Cleric can cast _Sunray,_ A spell that deals _2-8 damage_ and blinds the target for _4 turns,_ at the cost of 1 charge.\n\n_+2:_ The Cleric can cast _Sunray,_ A spell that deals _3-12 damage_ and blinds the target for _6 turns,_ at the cost of 1 charge.\n\nSunray can only blind each target once, but if the target is already blinded by Sunray then it paralyses instead. Sunray always deals maximum damage to demonic and undead foes.
|
||||
actors.hero.talent.divine_sense.title=Divine Sense
|
||||
|
||||
+10
-3
@@ -44,6 +44,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.WandEmpower;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.Ratmogrify;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.GuidingLight;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.RecallGlyph;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.FloatingText;
|
||||
@@ -57,6 +58,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.CloakOfShadows;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.HolyTome;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.HornOfPlenty;
|
||||
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.trinkets.ShardOfOblivion;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
|
||||
@@ -175,7 +177,7 @@ public enum Talent {
|
||||
//Cleric T1
|
||||
SATIATED_SPELLS(160), DETECT_CURSE(161), SEARING_LIGHT(162), SHIELD_OF_LIGHT(163),
|
||||
//Cleric T2
|
||||
ENLIGHTENING_MEAL(164), CLERICT2B(165), SUNRAY(166), DIVINE_SENSE(167), CLERICT2E(168),
|
||||
ENLIGHTENING_MEAL(164), RECALL_GLYPH(165), SUNRAY(166), DIVINE_SENSE(167), CLERICT2E(168),
|
||||
//Cleric T3
|
||||
CLERICT3A(169, 3), CLERICT3B(170, 3),
|
||||
|
||||
@@ -688,7 +690,7 @@ public enum Talent {
|
||||
}
|
||||
}
|
||||
|
||||
public static void onScrollUsed( Hero hero, int pos, float factor ){
|
||||
public static void onScrollUsed( Hero hero, int pos, float factor, Class<?extends Item> cls ){
|
||||
if (hero.hasTalent(INSCRIBED_POWER)){
|
||||
// 2/3 empowered wand zaps
|
||||
Buff.affect(hero, ScrollEmpower.class).reset((int) (factor * (1 + hero.pointsInTalent(INSCRIBED_POWER))));
|
||||
@@ -698,6 +700,11 @@ public enum Talent {
|
||||
Buff.affect(hero, Invisibility.class, factor * (1 + 2*hero.pointsInTalent(INSCRIBED_STEALTH)));
|
||||
Sample.INSTANCE.play( Assets.Sounds.MELD );
|
||||
}
|
||||
if (hero.heroClass == HeroClass.CLERIC
|
||||
&& hero.hasTalent(RECALL_GLYPH)
|
||||
&& Scroll.class.isAssignableFrom(cls)){
|
||||
Buff.affect(hero, RecallGlyph.UsedGlyphTracker.class, hero.pointsInTalent(RECALL_GLYPH) == 2 ? 300 : 10).item = cls;
|
||||
}
|
||||
}
|
||||
|
||||
public static void onUpgradeScrollUsed( Hero hero ){
|
||||
@@ -915,7 +922,7 @@ public enum Talent {
|
||||
Collections.addAll(tierTalents, FOCUSED_MEAL, LIQUID_AGILITY, WEAPON_RECHARGING, LETHAL_HASTE, SWIFT_EQUIP);
|
||||
break;
|
||||
case CLERIC:
|
||||
Collections.addAll(tierTalents, ENLIGHTENING_MEAL, CLERICT2B, SUNRAY, DIVINE_SENSE, CLERICT2E);
|
||||
Collections.addAll(tierTalents, ENLIGHTENING_MEAL, RECALL_GLYPH, SUNRAY, DIVINE_SENSE, CLERICT2E);
|
||||
break;
|
||||
}
|
||||
for (Talent talent : tierTalents){
|
||||
|
||||
+8
@@ -41,6 +41,10 @@ public abstract class ClericSpell {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public boolean canCast( Hero hero ){
|
||||
return true;
|
||||
}
|
||||
|
||||
public String name(){
|
||||
return Messages.get(this, "name");
|
||||
}
|
||||
@@ -89,6 +93,10 @@ public abstract class ClericSpell {
|
||||
spells.add(Sunray.INSTANCE);
|
||||
}
|
||||
|
||||
if (cleric.hasTalent(Talent.RECALL_GLYPH)){
|
||||
spells.add(RecallGlyph.INSTANCE);
|
||||
}
|
||||
|
||||
if (cleric.hasTalent(Talent.DIVINE_SENSE)) {
|
||||
spells.add(DivineSense.INSTANCE);
|
||||
}
|
||||
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FlavourBuff;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.HolyTome;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTransmutation;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ExoticScroll;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfEnchantment;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ScrollOfMetamorphosis;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.stones.Runestone;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.stones.StoneOfAugmentation;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.stones.StoneOfEnchantment;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ui.HeroIcon;
|
||||
import com.watabou.utils.Bundle;
|
||||
import com.watabou.utils.Reflection;
|
||||
|
||||
public class RecallGlyph extends ClericSpell {
|
||||
|
||||
public static RecallGlyph INSTANCE = new RecallGlyph();
|
||||
|
||||
@Override
|
||||
public int icon() {
|
||||
return HeroIcon.RECALL_GLYPH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String desc() {
|
||||
return Messages.get(this, "desc", Dungeon.hero.pointsInTalent(Talent.RECALL_GLYPH) == 2 ? 300 : 10) + "\n\n" + Messages.get(this, "charge_cost", (int)chargeUse(Dungeon.hero));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCast(HolyTome tome, Hero hero) {
|
||||
|
||||
if (hero.buff(UsedGlyphTracker.class) == null){
|
||||
return;
|
||||
}
|
||||
|
||||
Item item = Reflection.newInstance(hero.buff(UsedGlyphTracker.class).item);
|
||||
|
||||
item.setCurrent(hero);
|
||||
|
||||
//TODO runestones
|
||||
if (item instanceof Scroll){
|
||||
((Scroll) item).anonymize();
|
||||
((Scroll) item).doRead();
|
||||
}
|
||||
|
||||
onSpellCast(tome, hero);
|
||||
hero.buff(UsedGlyphTracker.class).detach();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public float chargeUse(Hero hero) {
|
||||
if (hero.buff(UsedGlyphTracker.class) != null){
|
||||
Class<? extends Item> item = hero.buff(UsedGlyphTracker.class).item;
|
||||
if (ExoticScroll.class.isAssignableFrom(item)){
|
||||
if (item == ScrollOfMetamorphosis.class || item == ScrollOfEnchantment.class){
|
||||
return 6;
|
||||
} else {
|
||||
return 3;
|
||||
}
|
||||
} else if (Scroll.class.isAssignableFrom(item)){
|
||||
if (item == ScrollOfTransmutation.class){
|
||||
return 4;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
} else if (Runestone.class.isAssignableFrom(item)){
|
||||
if (item == StoneOfAugmentation.class || item == StoneOfEnchantment.class){
|
||||
return 2;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCast(Hero hero) {
|
||||
return hero.buff(UsedGlyphTracker.class) != null;
|
||||
}
|
||||
|
||||
public static class UsedGlyphTracker extends FlavourBuff {
|
||||
|
||||
{
|
||||
type = buffType.POSITIVE;
|
||||
}
|
||||
|
||||
public Class<?extends Item> item;
|
||||
|
||||
@Override
|
||||
public int icon() {
|
||||
return BuffIndicator.GLYPH_RECALL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float iconFadePercent() {
|
||||
float duration = Dungeon.hero.pointsInTalent(Talent.RECALL_GLYPH) == 2 ? 300 : 10;
|
||||
return Math.max(0, (duration - visualcooldown()) / duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String desc() {
|
||||
return Messages.get(this, "desc", Messages.titleCase(Reflection.newInstance(item).name()), dispTurns());
|
||||
}
|
||||
|
||||
private static String ITEM = "item";
|
||||
|
||||
@Override
|
||||
public void storeInBundle(Bundle bundle) {
|
||||
super.storeInBundle(bundle);
|
||||
bundle.put(ITEM, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreFromBundle(Bundle bundle) {
|
||||
super.restoreFromBundle(bundle);
|
||||
item = bundle.getClass(ITEM);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -687,6 +687,11 @@ public class Item implements Bundlable {
|
||||
|
||||
protected static Hero curUser = null;
|
||||
protected static Item curItem = null;
|
||||
public void setCurrent( Hero hero ){
|
||||
curUser = hero;
|
||||
curItem = this;
|
||||
}
|
||||
|
||||
protected static CellSelector.Listener thrower = new CellSelector.Listener() {
|
||||
@Override
|
||||
public void onSelect( Integer target ) {
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ public class HolyTome extends Artifact {
|
||||
}
|
||||
|
||||
public boolean canCast( Hero hero, ClericSpell spell ){
|
||||
return (charge >= spell.chargeUse(hero));
|
||||
return (charge >= spell.chargeUse(hero) && spell.canCast(hero));
|
||||
}
|
||||
|
||||
public void spendCharge( float chargesSpent ){
|
||||
|
||||
+1
-1
@@ -201,7 +201,7 @@ public abstract class Scroll extends Item {
|
||||
if (!anonymous) {
|
||||
Catalog.countUse(getClass());
|
||||
if (Random.Float() < talentChance) {
|
||||
Talent.onScrollUsed(curUser, curUser.pos, talentFactor);
|
||||
Talent.onScrollUsed(curUser, curUser.pos, talentFactor, getClass());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -261,7 +261,7 @@ public class Alchemize extends Spell {
|
||||
}
|
||||
Catalog.countUse(getClass());
|
||||
if (curItem instanceof Alchemize && Random.Float() < ((Alchemize)curItem).talentChance){
|
||||
Talent.onScrollUsed(curUser, curUser.pos, ((Alchemize) curItem).talentFactor);
|
||||
Talent.onScrollUsed(curUser, curUser.pos, ((Alchemize) curItem).talentFactor, curItem.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -176,7 +176,7 @@ public class BeaconOfReturning extends Spell {
|
||||
detach(hero.belongings.backpack);
|
||||
Catalog.countUse(getClass());
|
||||
if (Random.Float() < talentChance){
|
||||
Talent.onScrollUsed(curUser, curUser.pos, talentFactor);
|
||||
Talent.onScrollUsed(curUser, curUser.pos, talentFactor, getClass());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@ public abstract class InventorySpell extends Spell {
|
||||
|
||||
Catalog.countUse(curItem.getClass());
|
||||
if (Random.Float() < ((Spell) curItem).talentChance) {
|
||||
Talent.onScrollUsed(curUser, curUser.pos, ((Spell) curItem).talentFactor);
|
||||
Talent.onScrollUsed(curUser, curUser.pos, ((Spell) curItem).talentFactor, curItem.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ public class MagicalInfusion extends InventorySpell {
|
||||
|
||||
Catalog.countUse(curItem.getClass());
|
||||
if (Random.Float() < ((Spell) curItem).talentChance) {
|
||||
Talent.onScrollUsed(curUser, curUser.pos, ((Spell) curItem).talentFactor);
|
||||
Talent.onScrollUsed(curUser, curUser.pos, ((Spell) curItem).talentFactor, getClass());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -123,7 +123,7 @@ public class SummonElemental extends Spell {
|
||||
detach(Dungeon.hero.belongings.backpack);
|
||||
Catalog.countUse(getClass());
|
||||
if (Random.Float() < talentChance){
|
||||
Talent.onScrollUsed(curUser, curUser.pos, talentFactor);
|
||||
Talent.onScrollUsed(curUser, curUser.pos, talentFactor, getClass());
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ public abstract class TargetedSpell extends Spell {
|
||||
curUser.spendAndNext( 1f );
|
||||
Catalog.countUse(curSpell.getClass());
|
||||
if (Random.Float() < curSpell.talentChance){
|
||||
Talent.onScrollUsed(curUser, curUser.pos, curSpell.talentFactor);
|
||||
Talent.onScrollUsed(curUser, curUser.pos, curSpell.talentFactor, curSpell.getClass());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
+1
-1
@@ -115,7 +115,7 @@ public class UnstableSpell extends Spell {
|
||||
|
||||
Catalog.countUse(getClass());
|
||||
if (Random.Float() < talentChance){
|
||||
Talent.onScrollUsed(curUser, curUser.pos, talentFactor);
|
||||
Talent.onScrollUsed(curUser, curUser.pos, talentFactor, getClass());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -127,6 +127,7 @@ public class BuffIndicator extends Component {
|
||||
public static final int SPELL_FOOD = 75;
|
||||
public static final int LIGHT_SHIELD= 76;
|
||||
public static final int HOLY_SIGHT = 77;
|
||||
public static final int GLYPH_RECALL= 78;
|
||||
|
||||
public static final int SIZE_SMALL = 7;
|
||||
public static final int SIZE_LARGE = 16;
|
||||
|
||||
@@ -75,6 +75,7 @@ public class HeroIcon extends Image {
|
||||
public static final int DETECT_CURSE = 44;
|
||||
public static final int SUNRAY = 45;
|
||||
public static final int DIVINE_SENSE = 46;
|
||||
public static final int RECALL_GLYPH = 47;
|
||||
|
||||
//action indicator visuals
|
||||
public static final int BERSERK = 80;
|
||||
|
||||
Reference in New Issue
Block a user