diff --git a/core/src/main/assets/interfaces/buffs.png b/core/src/main/assets/interfaces/buffs.png index 5b5084448..59b3120ca 100644 Binary files a/core/src/main/assets/interfaces/buffs.png and b/core/src/main/assets/interfaces/buffs.png differ diff --git a/core/src/main/assets/interfaces/large_buffs.png b/core/src/main/assets/interfaces/large_buffs.png index 49c96da62..19fe65a52 100644 Binary files a/core/src/main/assets/interfaces/large_buffs.png and b/core/src/main/assets/interfaces/large_buffs.png differ diff --git a/core/src/main/assets/messages/actors/actors.properties b/core/src/main/assets/messages/actors/actors.properties index 1ae4e201d..ac8c6782e 100644 --- a/core/src/main/assets/messages/actors/actors.properties +++ b/core/src/main/assets/messages/actors/actors.properties @@ -548,6 +548,14 @@ actors.hero.abilities.cleric.ascendedform$ascendbuff.name=ascended form actors.hero.abilities.cleric.ascendedform$ascendbuff.desc=Radiant energy is emanating from the Cleric's body. While in this form the Cleric gains 2 attack range (from the holy energy projecting from them), and 10 shielding whenever they spend a holy tome charge. They are also able to cast the spells which are unlocked via ascended form's talents.\n\nThe shield granted by ascended form and its spells will not decay normally, but will instantly fade when ascended form ends.\n\nCurrent shielding: %1$d.\nTurns remaining: %2$d. actors.hero.abilities.cleric.trinity.name=trinity actors.hero.abilities.cleric.trinity.no_imbue=Trinity has no effect set for any of its forms currently, use one of its spells! +actors.hero.abilities.cleric.trinity.no_duplicate=Trinity cannot duplicate an effect that you already have equipped! +actors.hero.abilities.cleric.trinity.ench_glyph_use=Trinity will apply this effect for _%1$d turns_ at the cost of _%2$s charge._ +actors.hero.abilities.cleric.trinity.rare_ench_glyph_use=Trinity will apply this _powerful_ effect for _%1$d turns_ at the cost of _%2$s charge._ +actors.hero.abilities.cleric.trinity.wand_use=Trinity will zap this wand at _+%1$d_ at the cost of _%2$s charge._ +actors.hero.abilities.cleric.trinity.thrown_use=Trinity will throw this weapon at _+%1$d_ at the cost of _%2$s charge._ +actors.hero.abilities.cleric.trinity.ring_use=Trinity will apply this ring's effect at _+%1$d_ for 20 turns, at the cost of _%2$s charge._ +actors.hero.abilities.cleric.trinity.artifact_use=Trinity will apply this artifact's effect at _+%1$d_, at the cost of _%2$s charge._ +actors.hero.abilities.cleric.trinity.cost=The charge cost of this ability varies, but is most often _%d._ actors.hero.abilities.cleric.trinity.short_desc=The Cleric gains a _Trinity_ of abilities, which emulate equipment they have seen and can be assigned by using new spells. actors.hero.abilities.cleric.trinity.desc=The Cleric gains a _Trinity_ of armor abilities, which can be assigned to various item effects by using three new spells. Each of these spells focuses on emulating the effects of different kinds of equipment that the Cleric has identified during this run: body form (weapons and armor), mind form (wands and thrown weapons), and spirit form (rings and artifacts).\n\nEach Trinity form can be imbued with one effect at a time, and the Cleric chooses which one to activate when using Trinity. Trinity will not duplicate the effect of something you already have equipped. actors.hero.abilities.cleric.trinity$wndusetrinity.text=Select which form of Trinity to use. The effects of different forms can be active simultaneously. @@ -558,13 +566,6 @@ actors.hero.abilities.cleric.trinity$wnditemtypeselect.text=Select an effect to actors.hero.abilities.cleric.trinity$wnditemconfirm.body=Assign to body form actors.hero.abilities.cleric.trinity$wnditemconfirm.mind=Assign to mind form actors.hero.abilities.cleric.trinity$wnditemconfirm.spirit=Assign to spirit form -actors.hero.abilities.cleric.trinity.ench_glyph_use=Trinity will apply this effect for _%1$d turns_ at the cost of _%2$s charge._ -actors.hero.abilities.cleric.trinity.rare_ench_glyph_use=Trinity will apply this _powerful_ effect for _%1$d turns_ at the cost of _%2$s charge._ -actors.hero.abilities.cleric.trinity.wand_use=Trinity will zap this wand at _+%1$d_ at the cost of _%2$s charge._ -actors.hero.abilities.cleric.trinity.thrown_use=Trinity will throw this weapon at _+%1$d_ at the cost of _%2$s charge._ -actors.hero.abilities.cleric.trinity.ring_use=Trinity will apply this ring's effect at _+%1$d_ for 20 turns, at the cost of _%2$s charge._ -actors.hero.abilities.cleric.trinity.artifact_use=Trinity will apply this artifact's effect at _+%1$d_, at the cost of _%2$s charge._ -actors.hero.abilities.cleric.trinity.cost=The charge cost of this ability varies, but is most often _%d._ actors.hero.abilities.cleric.powerofmany.name=power of many actors.hero.abilities.cleric.powerofmany.short_desc=_(UNFINISHED)_ The Cleric channels the _Power of Many_, empowering an existing ally or creating a new one. actors.hero.abilities.cleric.powerofmany.desc=_Power of Many has not been implemented yet, and so is currently unselectable._ @@ -593,6 +594,8 @@ actors.hero.spells.blessspell.desc=The Cleric places a holy blessing on themselv actors.hero.spells.bodyform.name=body form actors.hero.spells.bodyform.short_desc=Assigns Trinity to an enchant or glyph. actors.hero.spells.bodyform.desc=The Cleric chooses an enchantment or glyph that they have identified this run and imbues Trinity with its effect.\n\nWhen Trinity is used, The Cleric gains the effect of the chosen enchantment or glyph for %d turns. This temporary enchant or glyph will work with any effect that a regular enchantment or glyph would.\n\nThis spell replaces any other body effect that Trinity is currently imbued with. +actors.hero.spells.bodyform$bodyformbuff.name=body form +actors.hero.spells.bodyform$bodyformbuff.desc=Trinity's body form is currently granting you the power of an enchantment or glyph, as if you had it equipped on your current weapon or armor.\n\nNote that body form cannot provide another copy of an effect that you're already benefitting from.\n\nCurrent Effect: %1$s.\n\nTurns Remaining: %2$s. actors.hero.spells.cleanse.name=cleanse actors.hero.spells.cleanse.short_desc=Clears debuffs and grants shielding. diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java index c68bb0165..90bffbe5a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/Hero.java @@ -70,6 +70,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.duelist.Ch import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.duelist.ElementalStrike; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.NaturesPower; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.warrior.Endure; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.BodyForm; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.HallowedGround; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.HolyWard; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.HolyWeapon; @@ -93,6 +94,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.KindOfWeapon; import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor; import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor; +import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClothArmor; import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Viscosity; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.AlchemistsToolkit; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.CapeOfThorns; @@ -140,6 +142,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Quarterstaff; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.RoundShield; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Sai; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Scimitar; +import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.WornShortsword; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon; import com.shatteredpixel.shatteredpixeldungeon.journal.Catalog; import com.shatteredpixel.shatteredpixeldungeon.journal.Document; @@ -1449,12 +1452,19 @@ public class Hero extends Char { if (wep != null) { damage = wep.proc( this, enemy, damage ); } else { - if (buff(HolyWeapon.HolyWepBuff.class) != null) { - int dmg = subClass == HeroSubClass.PALADIN ? 6 : 2; - enemy.damage(Math.round(dmg * Weapon.Enchantment.genericProcChanceMultiplier(this)), HolyWeapon.INSTANCE); + boolean wasEnemy = enemy.alignment == Alignment.ENEMY; + if (buff(BodyForm.BodyFormBuff.class) != null + && buff(BodyForm.BodyFormBuff.class).enchant() != null){ + damage = buff(BodyForm.BodyFormBuff.class).enchant().proc(new WornShortsword(), this, enemy, damage); } - if (buff(Smite.SmiteTracker.class) != null){ - enemy.damage(Smite.bonusDmg(this, enemy), Smite.INSTANCE); + if (!wasEnemy || enemy.alignment == Alignment.ENEMY) { + if (buff(HolyWeapon.HolyWepBuff.class) != null) { + int dmg = subClass == HeroSubClass.PALADIN ? 6 : 2; + enemy.damage(Math.round(dmg * Weapon.Enchantment.genericProcChanceMultiplier(this)), HolyWeapon.INSTANCE); + } + if (buff(Smite.SmiteTracker.class) != null) { + enemy.damage(Smite.bonusDmg(this, enemy), Smite.INSTANCE); + } } } @@ -1501,9 +1511,15 @@ public class Hero extends Char { if (belongings.armor() != null) { damage = belongings.armor().proc( enemy, this, damage ); - } else if (buff(HolyWard.HolyArmBuff.class) != null){ - int blocking = subClass == HeroSubClass.PALADIN ? 3 : 1; - damage -= Math.round(blocking * Armor.Glyph.genericProcChanceMultiplier(enemy)); + } else { + if (buff(BodyForm.BodyFormBuff.class) != null + && buff(BodyForm.BodyFormBuff.class).glyph() != null){ + damage = buff(BodyForm.BodyFormBuff.class).glyph().proc(new ClothArmor(), enemy, this, damage); + } + if (buff(HolyWard.HolyArmBuff.class) != null){ + int blocking = subClass == HeroSubClass.PALADIN ? 3 : 1; + damage -= Math.round(blocking * Armor.Glyph.genericProcChanceMultiplier(enemy)); + } } WandOfLivingEarth.RockArmor rockArmor = buff(WandOfLivingEarth.RockArmor.class); @@ -1518,6 +1534,10 @@ public class Hero extends Char { public int glyphLevel(Class cls) { if (belongings.armor() != null && belongings.armor().hasGlyph(cls, this)){ return Math.max(super.glyphLevel(cls), belongings.armor.buffedLvl()); + } else if (buff(BodyForm.BodyFormBuff.class) != null + && buff(BodyForm.BodyFormBuff.class).glyph() != null + && buff(BodyForm.BodyFormBuff.class).glyph().getClass() == cls){ + return belongings.armor() != null ? belongings.armor.buffedLvl() : 0; } else { return super.glyphLevel(cls); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/cleric/Trinity.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/cleric/Trinity.java index e32dd2e8f..b102362de 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/cleric/Trinity.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/cleric/Trinity.java @@ -24,6 +24,8 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.cleric; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Statistics; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbility; @@ -77,14 +79,14 @@ public class Trinity extends ArmorAbility { if (bodyForm == null && mindForm == null && spiritForm == null){ GLog.w(Messages.get(this, "no_imbue")); } else { - GameScene.show(new WndUseTrinity()); + GameScene.show(new WndUseTrinity(armor)); } } public class WndUseTrinity extends WndTitledMessage { - public WndUseTrinity() { + public WndUseTrinity(ClassArmor armor) { super(new HeroIcon(Trinity.this), Messages.titleCase(Trinity.this.name()), Messages.get(WndUseTrinity.class, "text")); @@ -100,26 +102,74 @@ public class Trinity extends ArmorAbility { + " " + trinityItemUseText(bodyForm.getClass()), 6){ @Override protected void onClick() { - //TODO + if (Dungeon.hero.belongings.weapon() != null && + ((Weapon)Dungeon.hero.belongings.weapon()).enchantment.getClass().equals(bodyForm.getClass())){ + GLog.w(Messages.get(Trinity.class, "no_duplicate")); + hide(); + } else { + Buff.affect(Dungeon.hero, BodyForm.BodyFormBuff.class, BodyForm.duration()).setEffect(bodyForm); + Sample.INSTANCE.play(Assets.Sounds.TELEPORT); + Weapon w = new WornShortsword(); + if (Dungeon.hero.belongings.weapon() != null) { + w.image = Dungeon.hero.belongings.weapon().image; + } + w.enchant((Weapon.Enchantment) bodyForm); + Enchanting.show(Dungeon.hero, w); + Dungeon.hero.sprite.operate(Dungeon.hero.pos); + Dungeon.hero.spendAndNext(1f); + armor.charge -= trinityChargeUsePerEffect(bodyForm.getClass()); + armor.updateQuickslot(); + Invisibility.dispel(); + hide(); + } } }; - btnBody.icon(new ItemSprite(ItemSpriteSheet.WORN_SHORTSWORD, ((Weapon.Enchantment) bodyForm).glowing())); + if (Dungeon.hero.belongings.weapon() != null) { + btnBody.icon(new ItemSprite(Dungeon.hero.belongings.weapon().image, ((Weapon.Enchantment) bodyForm).glowing())); + } else { + btnBody.icon(new ItemSprite(ItemSpriteSheet.WORN_SHORTSWORD, ((Weapon.Enchantment) bodyForm).glowing())); + } } else if (bodyForm instanceof Armor.Glyph){ btnBody = new RedButton(Messages.get(WndUseTrinity.class, "body", Messages.titleCase(((Armor.Glyph)bodyForm).name())) + " " + trinityItemUseText(bodyForm.getClass()), 6){ @Override protected void onClick() { - //TODO + if (Dungeon.hero.belongings.armor() != null && + (Dungeon.hero.belongings.armor()).glyph.getClass().equals(bodyForm.getClass())){ + GLog.w(Messages.get(Trinity.class, "no_duplicate")); + hide(); + } else { + Buff.affect(Dungeon.hero, BodyForm.BodyFormBuff.class, BodyForm.duration()).setEffect(bodyForm); + Sample.INSTANCE.play(Assets.Sounds.TELEPORT); + Armor a = new ClothArmor(); + if (Dungeon.hero.belongings.armor() != null) { + a.image = Dungeon.hero.belongings.armor().image; + } + a.inscribe((Armor.Glyph) bodyForm); + Enchanting.show(Dungeon.hero, a); + Dungeon.hero.sprite.operate(Dungeon.hero.pos); + Dungeon.hero.spendAndNext(1f); + armor.charge -= trinityChargeUsePerEffect(bodyForm.getClass()); + armor.updateQuickslot(); + Invisibility.dispel(); + hide(); + } } }; - btnBody.icon(new ItemSprite(ItemSpriteSheet.ARMOR_CLOTH, ((Armor.Glyph) bodyForm).glowing())); + if (Dungeon.hero.belongings.armor() != null) { + btnBody.icon(new ItemSprite(Dungeon.hero.belongings.armor().image, ((Armor.Glyph) bodyForm).glowing())); + } else { + btnBody.icon(new ItemSprite(ItemSpriteSheet.ARMOR_CLOTH, ((Armor.Glyph) bodyForm).glowing())); + } } btnBody.multiline = true; btnBody.setSize(width, 100); //for text layout btnBody.setRect(0, top + 2, width, btnBody.reqHeight()); add(btnBody); top = (int)btnBody.bottom(); + + btnBody.enable(armor.charge >= trinityChargeUsePerEffect(bodyForm.getClass())); } if (mindForm != null){ @@ -145,6 +195,12 @@ public class Trinity extends ArmorAbility { + " " + trinityItemUseText(spiritForm.getClass()), 6){ @Override protected void onClick() { + if (Dungeon.hero.belongings.ring().getClass().equals(spiritForm.getClass()) + || Dungeon.hero.belongings.misc().getClass().equals(spiritForm.getClass()) + || Dungeon.hero.belongings.artifact().getClass().equals(spiritForm.getClass())){ + GLog.w(Messages.get(Trinity.class, "no_duplicate")); + hide(); + } //TODO } }; @@ -241,10 +297,16 @@ public class Trinity extends ArmorAbility { for (Class cls : discoveredClasses){ if (Weapon.Enchantment.class.isAssignableFrom(cls)){ MeleeWeapon w = new WornShortsword(); + if (Dungeon.hero.belongings.weapon() != null){ + w.image = Dungeon.hero.belongings.weapon().image; + } w.enchant((Weapon.Enchantment) Reflection.newInstance(cls)); options.add(w); } else if (Armor.Glyph.class.isAssignableFrom(cls)) { Armor a = new ClothArmor(); + if (Dungeon.hero.belongings.armor() != null){ + a.image = Dungeon.hero.belongings.armor().image; + } a.inscribe((Armor.Glyph) Reflection.newInstance(cls)); options.add(a); } else { @@ -349,16 +411,16 @@ public class Trinity extends ArmorAbility { } public static String trinityItemUseText(Class cls ){ - float chargeUse = Dungeon.hero.armorAbility.chargeUse(Dungeon.hero); + float chargeUse = trinityChargeUsePerEffect(cls); if (Weapon.Enchantment.class.isAssignableFrom(cls) || Armor.Glyph.class.isAssignableFrom(cls)) { for (Class ench : Weapon.Enchantment.rare) { if (ench.equals(cls)) { - return Messages.get(Trinity.class, "rare_ench_glyph_use", BodyForm.duration(), Messages.decimalFormat("#.##", 2*chargeUse)); + return Messages.get(Trinity.class, "rare_ench_glyph_use", BodyForm.duration(), Messages.decimalFormat("#.##", chargeUse)); } } for (Class glyph : Armor.Glyph.rare){ if (glyph.equals(cls)){ - return Messages.get(Trinity.class, "rare_ench_glyph_use", BodyForm.duration(), Messages.decimalFormat("#.##", 2*chargeUse)); + return Messages.get(Trinity.class, "rare_ench_glyph_use", BodyForm.duration(), Messages.decimalFormat("#.##", chargeUse)); } } return Messages.get(Trinity.class, "ench_glyph_use", BodyForm.duration(), Messages.decimalFormat("#.##", chargeUse)); @@ -379,4 +441,25 @@ public class Trinity extends ArmorAbility { } + public static float trinityChargeUsePerEffect(Class cls){ + float chargeUse = Dungeon.hero.armorAbility.chargeUse(Dungeon.hero); + if (Weapon.Enchantment.class.isAssignableFrom(cls) || Armor.Glyph.class.isAssignableFrom(cls)) { + for (Class ench : Weapon.Enchantment.rare) { + if (ench.equals(cls)) { + return 2*chargeUse; + } + } + for (Class glyph : Armor.Glyph.rare){ + if (glyph.equals(cls)){ + return 2*chargeUse; + } + } + } + if (Artifact.class.isAssignableFrom(cls)){ + return chargeUse; //TODO + } + //all other effects are standard charge use + return chargeUse; + } + } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/BodyForm.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/BodyForm.java index e051cf329..d653ffb62 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/BodyForm.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/spells/BodyForm.java @@ -22,12 +22,20 @@ 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.actors.hero.abilities.cleric.Trinity; +import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.HolyTome; +import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon; +import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; +import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.HeroIcon; +import com.watabou.noosa.Image; +import com.watabou.utils.Bundlable; +import com.watabou.utils.Bundle; public class BodyForm extends ClericSpell { @@ -59,4 +67,70 @@ public class BodyForm extends ClericSpell { return Math.round(13.33f + 6.67f* Dungeon.hero.pointsInTalent(Talent.BODY_FORM)); } + public static class BodyFormBuff extends FlavourBuff { + + { + type = buffType.POSITIVE; + } + + private Bundlable effect; + + @Override + public int icon() { + return BuffIndicator.TRINITY_FORM; + } + + @Override + public void tintIcon(Image icon) { + icon.hardlight(1, 0, 0); + } + + @Override + public float iconFadePercent() { + return Math.max(0, (duration() - visualcooldown()) / duration()); + } + + public void setEffect(Bundlable effect){ + this.effect = effect; + } + + public Weapon.Enchantment enchant(){ + if (effect instanceof Weapon.Enchantment){ + return (Weapon.Enchantment) effect; + } + return null; + } + + public Armor.Glyph glyph(){ + if (effect instanceof Armor.Glyph){ + return (Armor.Glyph) effect; + } + return null; + } + + @Override + public String desc() { + if (enchant() != null){ + return Messages.get(this, "desc", Messages.titleCase(enchant().name()), dispTurns()); + } else if (glyph() != null){ + return Messages.get(this, "desc", Messages.titleCase(glyph().name()), dispTurns()); + } + return super.desc(); + } + + private static final String EFFECT = "effect"; + + @Override + public void storeInBundle(Bundle bundle) { + super.storeInBundle(bundle); + bundle.put(EFFECT, effect); + } + + @Override + public void restoreFromBundle(Bundle bundle) { + super.restoreFromBundle(bundle); + effect = bundle.get(EFFECT); + } + } + } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/Armor.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/Armor.java index 187761d2c..c8db53d57 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/Armor.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/Armor.java @@ -34,6 +34,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.spells.AuraOfProtection; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.BodyForm; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.HolyWard; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; import com.shatteredpixel.shatteredpixeldungeon.items.BrokenSeal; @@ -434,18 +435,33 @@ public class Armor extends EquipableItem { public int proc( Char attacker, Char defender, int damage ) { if (defender.buff(MagicImmune.class) == null) { + Glyph trinityGlyph = null; + if (Dungeon.hero.buff(BodyForm.BodyFormBuff.class) != null){ + trinityGlyph = Dungeon.hero.buff(BodyForm.BodyFormBuff.class).glyph(); + if (glyph != null && trinityGlyph != null && trinityGlyph.getClass() == glyph.getClass()){ + trinityGlyph = null; + } + } + if (defender instanceof Hero && isEquipped((Hero) defender) && defender.buff(HolyWard.HolyArmBuff.class) != null){ if (glyph != null && (((Hero) defender).subClass == HeroSubClass.PALADIN || hasCurseGlyph())){ damage = glyph.proc( this, attacker, defender, damage ); } + if (trinityGlyph != null){ + damage = trinityGlyph.proc( this, attacker, defender, damage ); + } int blocking = ((Hero) defender).subClass == HeroSubClass.PALADIN ? 3 : 1; damage -= Math.round(blocking * Glyph.genericProcChanceMultiplier(defender)); + } else { if (glyph != null) { damage = glyph.proc(this, attacker, defender, damage); } + if (trinityGlyph != null){ + damage = trinityGlyph.proc( this, attacker, defender, damage ); + } //so that this effect procs for allies using this armor via aura of protection if (defender.alignment == Dungeon.hero.alignment && Dungeon.level.distance(defender.pos, Dungeon.hero.pos) <= 2 diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/Weapon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/Weapon.java index 987ef3782..0e81b88d1 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/Weapon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/Weapon.java @@ -32,6 +32,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroSubClass; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.cleric.AscendedForm; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.duelist.ElementalStrike; +import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.BodyForm; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.HolyWeapon; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.spells.Smite; import com.shatteredpixel.shatteredpixeldungeon.items.Item; @@ -122,6 +123,15 @@ abstract public class Weapon extends KindOfWeapon { boolean becameAlly = false; boolean wasAlly = defender.alignment == Char.Alignment.ALLY; if (attacker.buff(MagicImmune.class) == null) { + //TODO body form + Enchantment trinityEnchant = null; + if (Dungeon.hero.buff(BodyForm.BodyFormBuff.class) != null){ + trinityEnchant = Dungeon.hero.buff(BodyForm.BodyFormBuff.class).enchant(); + if (enchantment != null && trinityEnchant != null && trinityEnchant.getClass() == enchantment.getClass()){ + trinityEnchant = null; + } + } + if (attacker instanceof Hero && isEquipped((Hero) attacker) && attacker.buff(HolyWeapon.HolyWepBuff.class) != null){ if (enchantment != null && @@ -131,16 +141,27 @@ abstract public class Weapon extends KindOfWeapon { becameAlly = true; } } + if (defender.isAlive() && !becameAlly && trinityEnchant != null){ + damage = trinityEnchant.proc(this, attacker, defender, damage); + } if (defender.isAlive() && !becameAlly) { int dmg = ((Hero) attacker).subClass == HeroSubClass.PALADIN ? 6 : 2; defender.damage(Math.round(dmg * Enchantment.genericProcChanceMultiplier(attacker)), HolyWeapon.INSTANCE); } - } else if (enchantment != null) { - damage = enchantment.proc(this, attacker, defender, damage); - if (defender.alignment == Char.Alignment.ALLY && !wasAlly){ - becameAlly = true; + + } else { + if (enchantment != null) { + damage = enchantment.proc(this, attacker, defender, damage); + if (defender.alignment == Char.Alignment.ALLY && !wasAlly) { + becameAlly = true; + } + } + + if (defender.isAlive() && !becameAlly && trinityEnchant != null){ + damage = trinityEnchant.proc(this, attacker, defender, damage); } } + if (attacker instanceof Hero && isEquipped((Hero) attacker) && attacker.buff(Smite.SmiteTracker.class) != null && !becameAlly){ defender.damage(Smite.bonusDmg((Hero) attacker, defender), Smite.INSTANCE); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java index 63982801c..646975644 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/ui/BuffIndicator.java @@ -131,6 +131,7 @@ public class BuffIndicator extends Component { public static final int ASCEND = 79; public static final int PROT_AURA = 80; public static final int ILLUMINATED = 81; + public static final int TRINITY_FORM= 82; public static final int SIZE_SMALL = 7; public static final int SIZE_LARGE = 16;