diff --git a/core/src/main/assets/interfaces/hero_icons.png b/core/src/main/assets/interfaces/hero_icons.png index 5c506ce88..52a2d638a 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/talent_icons.png b/core/src/main/assets/interfaces/talent_icons.png index 7fe590edc..3878a31be 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 a0084eb49..2c6f6121f 100644 --- a/core/src/main/assets/messages/actors/actors.properties +++ b/core/src/main/assets/messages/actors/actors.properties @@ -544,6 +544,10 @@ actors.hero.abilities.ratmogrify$transmograt.desc=This enemy has been transforme actors.hero.abilities.ratmogrify$transmograt.rankings_desc=Slain by: ratmogrified enemy ##Cleric Spells +actors.hero.spells.cleanse.name=cleanse +actors.hero.spells.cleanse.short_desc=Clears debuffs and grants shielding. +actors.hero.spells.cleanse.desc=The Cleric instantly clears all harmful effects on themselves and visible allies. After the spell ends all characters affected also gain %1$d turns of debuff immunity, and %2$d barrier. + actors.hero.spells.clericspell.no_target=There is no target there. actors.hero.spells.clericspell.charge_cost=Charge cost: %d @@ -1070,8 +1074,8 @@ actors.hero.talent.divine_sense.desc=_+1:_ The Cleric can cast _Divine Sense,_ a actors.hero.talent.clerict2e.title=Unknown actors.hero.talent.clerict2e.desc=This talent hasn't been implemented yet, it currently does nothing. -actors.hero.talent.clerict3a.title=Unknown -actors.hero.talent.clerict3a.desc=This talent hasn't been implemented yet, it currently does nothing. +actors.hero.talent.cleanse.title=Cleanse +actors.hero.talent.cleanse.desc=_+1:_ The Cleric can cast _Cleanse,_ a spell which is cast instantly, _removes negative status effects_ from the Priest and any nearby allies, and grants them _10 shielding,_ at the cost of 2 charges.\n\n_+2:_ The Cleric can cast _Cleanse,_ a spell which is cast instantly, _grants 3 turns of negative status immunity_ to the Priest and any nearby allies, and grants them _20 shielding,_ at the cost of 2 charges.\n\n_+3:_ The Cleric can cast _Cleanse,_ a spell which is cast instantly, _grants 5 turns of negative status immunity_ to the Priest and any nearby allies, and grants them _30 shielding,_ at the cost of 2 charges. actors.hero.talent.light_reading.title=Light Reading actors.hero.talent.light_reading.desc=_+1:_ The Cleric can use his holy tome when it is not equipped, but it recharges at _25% speed_ when unequipped.\n\n_+2:_ The Cleric can use his holy tome when it is not equipped, but it recharges at _50% speed_ when unequipped.\n\n_+3:_ The Cleric can use his holy tome when it is not equipped, but it recharges at _75% speed_ when unequipped. diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Talent.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Talent.java index 30be6f7f0..2cdebc884 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Talent.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Talent.java @@ -179,7 +179,7 @@ public enum Talent { //Cleric T2 ENLIGHTENING_MEAL(164), RECALL_GLYPH(165), SUNRAY(166), DIVINE_SENSE(167), CLERICT2E(168), //Cleric T3 - CLERICT3A(169, 3), LIGHT_READING(170, 3), + CLEANSE(169, 3), LIGHT_READING(170, 3), //Priest T3 HOLY_LANCE(171, 3), PRIESTT3B(172, 3), PRIESTT3C(173, 3), //Paladin T3 @@ -964,7 +964,7 @@ public enum Talent { Collections.addAll(tierTalents, PRECISE_ASSAULT, DEADLY_FOLLOWUP); break; case CLERIC: - Collections.addAll(tierTalents, CLERICT3A, LIGHT_READING); + Collections.addAll(tierTalents, CLEANSE, LIGHT_READING); break; } for (Talent talent : tierTalents){ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/Cleanse.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/Cleanse.java new file mode 100644 index 000000000..8fbe10095 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/Cleanse.java @@ -0,0 +1,101 @@ +/* + * 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.actors.hero.spells; + +import com.shatteredpixel.shatteredpixeldungeon.Assets; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.AllyBuff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Barrier; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.LostInventory; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent; +import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; +import com.shatteredpixel.shatteredpixeldungeon.effects.Flare; +import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.HolyTome; +import com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.PotionOfCleansing; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; +import com.shatteredpixel.shatteredpixeldungeon.ui.HeroIcon; +import com.watabou.noosa.audio.Sample; + +import java.util.ArrayList; + +public class Cleanse extends ClericSpell { + + public static Cleanse INSTANCE = new Cleanse(); + + @Override + public int icon() { + return HeroIcon.CLEANSE; + } + + @Override + public float chargeUse(Hero hero) { + return 2; + } + + public String desc(){ + int immunity = 2 * (Dungeon.hero.pointsInTalent(Talent.CLEANSE)-1); + if (immunity > 0) immunity++; + int shield = 10 * Dungeon.hero.pointsInTalent(Talent.CLEANSE); + return Messages.get(this, "desc", immunity, shield) + "\n\n" + Messages.get(this, "charge_cost", (int)chargeUse(Dungeon.hero)); + } + + @Override + public void onCast(HolyTome tome, Hero hero) { + + ArrayList affected = new ArrayList<>(); + affected.add(hero); + + for (Mob mob : Dungeon.level.mobs.toArray( new Mob[0] )) { + if (Dungeon.level.heroFOV[mob.pos] && mob.alignment == Char.Alignment.ALLY) { + affected.add(mob); + } + } + + for (Char ch : affected) { + for (Buff b : ch.buffs()) { + if (b.type == Buff.buffType.NEGATIVE + && !(b instanceof AllyBuff) + && !(b instanceof LostInventory)) { + b.detach(); + } + } + + if (hero.pointsInTalent(Talent.CLEANSE) > 1) { + //0, 2, or 4. 1 less than displayed as spell is instant + Buff.affect(ch, PotionOfCleansing.Cleanse.class, 2 * (Dungeon.hero.pointsInTalent(Talent.CLEANSE)-1)); + } + Buff.affect(ch, Barrier.class).setShield(10 * hero.pointsInTalent(Talent.CLEANSE)); + new Flare( 6, 32 ).color(0xFF4CD2, true).show( ch.sprite, 2f ); + } + + hero.busy(); + hero.sprite.operate(hero.pos); + Sample.INSTANCE.play(Assets.Sounds.READ); + + onSpellCast(tome, hero); + + } + +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/ClericSpell.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/ClericSpell.java index 1744c5123..ca801f2f8 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/ClericSpell.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/ClericSpell.java @@ -104,6 +104,10 @@ public abstract class ClericSpell { } else if (tier == 3){ + if (cleric.hasTalent(Talent.CLEANSE)){ + spells.add(Cleanse.INSTANCE); + } + if (cleric.subClass == HeroSubClass.PRIEST) { spells.add(Radiance.INSTANCE); @@ -131,6 +135,7 @@ public abstract class ClericSpell { spells.add(Sunray.INSTANCE); spells.add(RecallGlyph.INSTANCE); spells.add(DivineSense.INSTANCE); + spells.add(Cleanse.INSTANCE); spells.add(Radiance.INSTANCE); spells.add(HolyLance.INSTANCE); return spells; 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 666518226..acc2c4392 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/HeroIcon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/HeroIcon.java @@ -83,6 +83,7 @@ public class HeroIcon extends Image { public static final int RECALL_GLYPH = 47; public static final int HOLY_LANCE = 48; public static final int RADIANCE = 49; + public static final int CLEANSE = 50; //all cleric spells have a separate icon with no background for the action indicator public static final int SPELL_ACTION_OFFSET = 32;