v3.0.0: implemented Priest's Guiding Light buff

This commit is contained in:
Evan Debenham
2024-11-20 13:19:55 -05:00
parent a1e8bdb1b3
commit a6df18c337
11 changed files with 89 additions and 9 deletions

View File

@@ -564,6 +564,9 @@ actors.hero.spells.guidinglight.name=guiding light
actors.hero.spells.guidinglight.prompt=Choose a target
actors.hero.spells.guidinglight.short_desc=Deals ranged magic damage and guarantees a hit.
actors.hero.spells.guidinglight.desc=The Cleric fires a bolt of magical energy which strikes a target, dealing 2-6 damage and illuminating them. The next physical attack made against an illuminated enemy is guaranteed to hit them.
actors.hero.spells.guidinglight.desc_priest=_This spell is more powerful when cast by the Priest._ The first cast of the spell every 100 turns costs no tome charges, and illumination can be triggered by wands and some artifacts, dealing bonus damage equal to the item's level plus five.
actors.hero.spells.guidinglight$guidinglightpriestcooldown.name=Guiding Light
actors.hero.spells.guidinglight$guidinglightpriestcooldown.desc=The Priest will be able to cast Guiding Light for free again after 100 turns elapse.\n\nTurns remaining: %s.
actors.hero.spells.holyward.name=holy ward
actors.hero.spells.holyward.glyph_name=%s of light
@@ -681,9 +684,9 @@ actors.hero.herosubclass.monk_short_desc=The _Monk_ builds energy while fighting
actors.hero.herosubclass.monk_desc=The Monk is a master of physical technique. As she defeats enemies, she gains energy which can be used on a variety of defensive and utility-focused abilities. This energy does not fade over time, but has a cap based on the Monk's level.\n\n1 Energy: quickly strike with fists\n2 Energy: focus to dodge next attack\n3 Energy: instantly dash nearby\n4 Energy: kick an enemy away\n5 Energy: meditate to clear statuses and restore wand & artifact charge
actors.hero.herosubclass.priest=priest
actors.hero.herosubclass.priest_short_desc=The _Priest_ gains new long-range spells and an empowered version of guiding light.
actors.hero.herosubclass.priest_desc=_The Priest has not been implemented yet, and so is currently unselectable_\n\nThe Priest gains a variety of new and upgraded spells that emphasize ranged combat and synergy with magical items.\n\nThe Priest can cast _Guiding Light_ for free once every 100 turns, and can trigger the illumination debuff with wands or artifacts for bonus damage.\n\nThey also gain the _Radiance_ spell, which dispels darkness and illuminates and momentarily stuns all visible enemies at the cost of 2 charges.
actors.hero.herosubclass.priest_desc=The Priest gains a variety of new and upgraded spells that emphasize ranged combat and synergy with magical items.\n\nThe Priest can cast _Guiding Light_ for free once every 100 turns, and can trigger the illumination debuff with wands and some artifacts for bonus damage.\n\nThey also gain the _Radiance_ spell, which dispels darkness and illuminates and momentarily stuns all visible enemies at the cost of 2 charges.
actors.hero.herosubclass.paladin=paladin
actors.hero.herosubclass.paladin_short_desc=The _Paladin_ gains new short-range spells and empowered versions of holy weapon and ward.
actors.hero.herosubclass.paladin_short_desc=_(UNFINISHED)_ The _Paladin_ gains new short-range spells and empowered versions of holy weapon and ward.
actors.hero.herosubclass.paladin_desc=_The Paladin has not been implemented yet, and so is currently unselectable_\n\nThe Paladin gains a variety of new and upgraded spells that emphasize melee combat and synergy with weapons and armor.\n\nThe Paladin's _Holy Weapon_ and _Holy Ward_ spells grant larger bonuses, and no longer override existing enchantments and glyphs.\n\nThey also gain the _Smite_ spell, which lets them perform a guaranteed melee hit with bonus damage and enchantment power.
##talents

View File

@@ -829,8 +829,8 @@ public enum Talent {
}
}
if (enemy.buff(GuidingLight.GuidingLightDebuff.class) != null){
enemy.buff(GuidingLight.GuidingLightDebuff.class).detach();
if (enemy.buff(GuidingLight.Illuminated.class) != null){
enemy.buff(GuidingLight.Illuminated.class).detach();
if (hero.hasTalent(Talent.SEARING_LIGHT)){
dmg += 1 + 2*hero.pointsInTalent(Talent.SEARING_LIGHT);
}

View File

@@ -22,18 +22,23 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
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.FlavourBuff;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
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.sprites.CharSprite;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
import com.shatteredpixel.shatteredpixeldungeon.ui.HeroIcon;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.Image;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Callback;
import com.watabou.utils.Random;
@@ -73,7 +78,7 @@ public class GuidingLight extends TargetedClericSpell {
Sample.INSTANCE.play(Assets.Sounds.HIT_MAGIC, 1, Random.Float(0.87f, 1.15f));
ch.sprite.burst(0xFFFFFF44, 3);
if (ch.isAlive()){
Buff.affect(ch, GuidingLightDebuff.class);
Buff.affect(ch, Illuminated.class);
}
}
@@ -81,12 +86,51 @@ public class GuidingLight extends TargetedClericSpell {
hero.next();
onSpellCast(tome, hero);
Buff.affect(hero, GuidingLightPriestCooldown.class, 100f);
}
});
}
public static class GuidingLightDebuff extends Buff {
@Override
public float chargeUse(Hero hero) {
if (hero.subClass == HeroSubClass.PRIEST
&& hero.buff(GuidingLightPriestCooldown.class) == null){
return 0;
} else {
return 1;
}
}
public String desc(){
String desc = Messages.get(this, "desc");
if (Dungeon.hero.subClass == HeroSubClass.PRIEST){
desc += "\n\n" + Messages.get(this, "desc_priest");
}
return desc + "\n\n" + Messages.get(this, "charge_cost", (int)chargeUse(Dungeon.hero));
}
public static class GuidingLightPriestCooldown extends FlavourBuff {
@Override
public int icon() {
return BuffIndicator.TIME;
}
@Override
public void tintIcon(Image icon) {
icon.hardlight(0.67f, 0.67f, 0);
}
public float iconFadePercent() { return Math.max(0, visualcooldown() / 100); }
}
public static class Illuminated extends Buff {
{
type = buffType.NEGATIVE;
}
@Override
public void fx(boolean on) {

View File

@@ -667,7 +667,7 @@ public abstract class Mob extends Char {
public int defenseSkill( Char enemy ) {
if ( !surprisedBy(enemy)
&& paralysed == 0
&& buff(GuidingLight.GuidingLightDebuff.class) == null
&& buff(GuidingLight.Illuminated.class) == null
&& !(alignment == Alignment.ALLY && enemy == Dungeon.hero)) {
return this.defenseSkill;
} else {

View File

@@ -26,6 +26,8 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicImmune;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.GuidingLight;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.KindofMisc;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
@@ -135,6 +137,21 @@ public class Artifact extends KindofMisc {
upgrade(Math.round((transferLvl*levelCap)/10f));
}
//TODO CLERIC consider all the cases in which this might happen, atm it's fairly conservative
// Currently works with 4/10 artifacts, could also:
// It should definitely trigger from unstable spellbook
// could possibly trigger from dried rose ghost melee
// maybe from hitting a target while time frozen from hourglass?
// could trigger from items crafted via toolkit? That's a big stretch
// makes no sense with horn, unless I work out some kind of self-buff that then applies to melee or spells
// 0 sense with chalice in all cases
public static void artifactProc(Char target, int artifLevel, int chargesUsed){
if (Dungeon.hero.subClass == HeroSubClass.PRIEST && target.buff(GuidingLight.Illuminated.class) != null) {
target.buff(GuidingLight.Illuminated.class).detach();
target.damage(5 + artifLevel, GuidingLight.INSTANCE);
}
}
@Override
public String info() {
if (cursed && cursedKnown && !isEquipped( Dungeon.hero )) {

View File

@@ -198,6 +198,8 @@ public class EtherealChains extends Artifact {
Dungeon.observe();
GameScene.updateFog();
hero.spendAndNext(1f);
artifactProc(enemy, visiblyUpgraded(), chargeUse);
}
}));
hero.next();

View File

@@ -180,6 +180,8 @@ public class MasterThievesArmband extends Artifact {
Buff.prolong(ch, Blindness.class, debuffDuration);
Buff.prolong(ch, Cripple.class, debuffDuration);
artifactProc(ch, visiblyUpgraded(), 1);
charge--;
exp += 3;
Talent.onArtifactUsed(Dungeon.hero);

View File

@@ -345,6 +345,10 @@ public class SandalsOfNature extends Artifact {
Sample.INSTANCE.play(Assets.Sounds.PLANT);
Sample.INSTANCE.playDelayed(Assets.Sounds.TRAMPLE, 0.25f, 1, Random.Float( 0.96f, 1.05f ) );
if (Actor.findChar(cell) != null){
artifactProc(Actor.findChar(cell), visiblyUpgraded(), seedChargeReqs.get(curSeedEffect));
}
charge -= seedChargeReqs.get(curSeedEffect);
Talent.onArtifactUsed(Dungeon.hero);
updateQuickslot();

View File

@@ -190,6 +190,8 @@ public class TalismanOfForesight extends Artifact {
if (ch != null && ch.alignment != Char.Alignment.NEUTRAL && ch.alignment != curUser.alignment){
Buff.append(curUser, CharAwareness.class, 5 + 2*level()).charID = ch.id();
artifactProc(ch, visiblyUpgraded(), (int)(3 + dist*1.08f));
if (!curUser.fieldOfView[ch.pos]){
earnedExp += 10;
}

View File

@@ -40,6 +40,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.mage.WildMagic;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.GuidingLight;
import com.shatteredpixel.shatteredpixeldungeon.effects.FloatingText;
import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
@@ -214,6 +215,11 @@ public abstract class Wand extends Item {
Random.Float() > (Math.pow(0.92f, (wandLevel*chargesUsed)+1) - 0.07f)){
SoulMark.prolong(target, SoulMark.class, SoulMark.DURATION + wandLevel);
}
if (Dungeon.hero.subClass == HeroSubClass.PRIEST && target.buff(GuidingLight.Illuminated.class) != null) {
target.buff(GuidingLight.Illuminated.class).detach();
target.damage(5 + wandLevel, GuidingLight.INSTANCE);
}
}
@Override

View File

@@ -84,8 +84,8 @@ public class WndChooseSubclass extends Window {
btnCls.setRect( 0, pos, WIDTH-20, btnCls.reqHeight()+2);
add( btnCls );
//TODO CLERIC neither subclass is actually playable atm
if (subCls == HeroSubClass.PRIEST || subCls == HeroSubClass.PALADIN){
//TODO CLERIC paladin is not implemented yet
if (subCls == HeroSubClass.PALADIN){
btnCls.enable(false);
}