diff --git a/core/src/main/assets/messages/actors/actors.properties b/core/src/main/assets/messages/actors/actors.properties index e3855bace..496fff939 100644 --- a/core/src/main/assets/messages/actors/actors.properties +++ b/core/src/main/assets/messages/actors/actors.properties @@ -565,6 +565,10 @@ actors.hero.spells.divinesense.desc=The Cleric focuses their senses on their sur actors.hero.spells.divinesense$divinesensetracker.name=divine sense actors.hero.spells.divinesense$divinesensetracker.desc=The Cleric is temporarily able to see other nearby creatures with their mind!\n\nTurns remaining: %s. +actors.hero.spells.divineintervention.name=divine intervention +actors.hero.spells.divineintervention.short_desc=Massive shield boost to Cleric and allies. +actors.hero.spells.divineintervention.desc=TODO + actors.hero.spells.flash.name=flash actors.hero.spells.flash.prompt=Choose a location actors.hero.spells.flash.short_desc=Teleport to a nearby location. @@ -612,6 +616,10 @@ 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 Remaining: %s. +actors.hero.spells.judgement.name=judgement +actors.hero.spells.judgement.short_desc=Damages all visible enemies. +actors.hero.spells.judgement.desc=TODO + actors.hero.spells.mnemonicprayer.name=mnemonic prayer actors.hero.spells.mnemonicprayer.short_desc=Extends buffs/debuffs on an ally/enemy, & re-applies illuminated. actors.hero.spells.mnemonicprayer.desc=The Priest utters a prayer that extends the duration of all buffs or debuffs on a specific target by %1$d turns. Positive effects will last longer on allies (including the Priest themselves), and harmful effects will last longer on enemies. This spell will also re-apply illuminated to an enemy that has been illuminated previously.\n\nMnemonic Prayer can only extend a specific instance of a buff or debuff once, and cannot extend buffs granted from armor abilities. diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/cleric/AscendedForm.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/cleric/AscendedForm.java index a8ba6a4dc..6fd8ed0e9 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/cleric/AscendedForm.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/cleric/AscendedForm.java @@ -23,12 +23,14 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.cleric; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ShieldBuff; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.DivineIntervention; import com.shatteredpixel.shatteredpixeldungeon.effects.Flare; import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; @@ -112,7 +114,11 @@ public class AscendedForm extends ArmorAbility { left--; if (left <= 0){ detach(); - //TODO also remove divine intervention shield from allies + for (Char ch : Actor.chars()){ + if (ch.buff(DivineIntervention.DivineShield.class) != null){ + ch.buff(DivineIntervention.DivineShield.class).detach(); + } + } return true; } 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 8261067f6..b9e578754 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 @@ -140,11 +140,11 @@ public abstract class ClericSpell { } else if (tier == 4){ if (cleric.hasTalent(Talent.DIVINE_INTERVENTION)){ - //TODO + spells.add(DivineIntervention.INSTANCE); } if (cleric.hasTalent(Talent.JUDGEMENT)){ - //TODO + spells.add(Judgement.INSTANCE); } if (cleric.hasTalent(Talent.FLASH)){ @@ -172,6 +172,9 @@ public abstract class ClericSpell { spells.add(HolyLance.INSTANCE); spells.add(HallowedGround.INSTANCE); spells.add(MnemonicPrayer.INSTANCE); + spells.add(DivineIntervention.INSTANCE); + spells.add(Judgement.INSTANCE); + spells.add(Flash.INSTANCE); return spells; } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/DivineIntervention.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/DivineIntervention.java new file mode 100644 index 000000000..d2949a618 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/DivineIntervention.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.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.ShieldBuff; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.cleric.AscendedForm; +import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.HolyTome; +import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite; +import com.shatteredpixel.shatteredpixeldungeon.ui.HeroIcon; + +public class DivineIntervention extends ClericSpell { + + public static DivineIntervention INSTANCE = new DivineIntervention(); + + @Override + public int icon() { + return HeroIcon.DIVINE_INTERVENTION; + } + + @Override + public float chargeUse(Hero hero) { + return 2; //TODO + } + + @Override + public boolean canCast(Hero hero) { + return super.canCast(hero) && hero.buff(AscendedForm.AscendBuff.class) != null; + } + + @Override + public void onCast(HolyTome tome, Hero hero) { + + //TODO vfx + + for (Char ch : Actor.chars()){ + if (ch.alignment == Char.Alignment.ALLY && ch != hero){ + Buff.affect(ch, DivineShield.class).setShield(150 + 50*hero.pointsInTalent(Talent.DIVINE_INTERVENTION)); + } + } + + hero.spendAndNext( 1f ); + onSpellCast(tome, hero); + + //we apply buffs here so that the 6 charge cost and shield boost do not stack + hero.buff(AscendedForm.AscendBuff.class).setShield(150 + 50*hero.pointsInTalent(Talent.DIVINE_INTERVENTION)); + + } + + public static class DivineShield extends ShieldBuff{ + + @Override + public boolean act() { + + if (Dungeon.hero == null || Dungeon.hero.buff(AscendedForm.AscendBuff.class) == null){ + detach(); + } + + spend(TICK); + return true; + } + + @Override + public int shielding() { + if (Dungeon.hero == null || Dungeon.hero.buff(AscendedForm.AscendBuff.class) == null){ + return 0; + } + return super.shielding(); + } + + @Override + public void fx(boolean on) { + if (on) target.sprite.add(CharSprite.State.SHIELDED); + else target.sprite.remove(CharSprite.State.SHIELDED); + } + } +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/Judgement.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/Judgement.java new file mode 100644 index 000000000..0a7593667 --- /dev/null +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/Judgement.java @@ -0,0 +1,73 @@ +/* + * 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.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; +import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.cleric.AscendedForm; +import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.HolyTome; +import com.shatteredpixel.shatteredpixeldungeon.ui.HeroIcon; +import com.watabou.utils.Random; + +public class Judgement extends ClericSpell { + + public static Judgement INSTANCE = new Judgement(); + + @Override + public int icon() { + return HeroIcon.JUDGEMENT; + } + + @Override + public float chargeUse(Hero hero) { + return 3; + } + + @Override + public boolean canCast(Hero hero) { + return super.canCast(hero) && hero.buff(AscendedForm.AscendBuff.class) != null; + } + + @Override + public void onCast(HolyTome tome, Hero hero) { + + //TODO vfx + + int damageBase = 5 + 5*hero.pointsInTalent(Talent.JUDGEMENT); + damageBase += 5*hero.buff(AscendedForm.AscendBuff.class).spellCasts; + + for (Char ch : Actor.chars()){ + if (ch.alignment != hero.alignment && Dungeon.level.heroFOV[ch.pos]){ + ch.damage( Random.NormalIntRange(damageBase, 2*damageBase), Judgement.this); + } + } + + hero.spendAndNext( 1f ); + onSpellCast(tome, hero); + + hero.buff(AscendedForm.AscendBuff.class).spellCasts = 0; + + } +} diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/AntiMagic.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/AntiMagic.java index d654a6702..c64e81cfc 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/AntiMagic.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/AntiMagic.java @@ -28,6 +28,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Hex; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicalSleep; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Vulnerable; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Weakness; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.Judgement; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.duelist.ElementalStrike; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.mage.ElementalBlast; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.mage.WarpBeacon; @@ -96,6 +97,7 @@ public class AntiMagic extends Armor.Glyph { RESISTS.add( HolyWeapon.class ); RESISTS.add( Sunray.class ); RESISTS.add( HolyLance.class ); + RESISTS.add( Judgement.class ); RESISTS.add( ElementalBlast.class ); RESISTS.add( CursedWand.class ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoTalent.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoTalent.java index a5f7131dc..d62933190 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoTalent.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/windows/WndInfoTalent.java @@ -64,7 +64,7 @@ public class WndInfoTalent extends Window { add( txtInfo ); while (PixelScene.landscape() - && txtInfo.height() > 100 + && txtInfo.height() > 120 && width < WIDTH_MAX){ width += 20; txtInfo.maxWidth(width);