From d556f966cca06ff8b47836f2a7b46f6759f537d1 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Mon, 20 Jan 2025 12:00:47 -0500 Subject: [PATCH] v3.0.0: substantially improved code for non-proc glyph fx --- .../shatteredpixeldungeon/actors/Char.java | 33 ++++++++++++-- .../actors/buffs/Burning.java | 6 +-- .../actors/hero/Hero.java | 42 +++++------------ .../hero/abilities/rogue/ShadowClone.java | 31 +++---------- .../actors/mobs/ArmoredStatue.java | 40 +++-------------- .../actors/mobs/npcs/PrismaticImage.java | 40 ++++------------- .../items/armor/Armor.java | 41 ----------------- .../items/armor/curses/Bulk.java | 15 ++++++- .../items/armor/glyphs/AntiMagic.java | 19 ++++---- .../items/armor/glyphs/Brimstone.java | 7 +-- .../items/armor/glyphs/Camouflage.java | 3 +- .../items/armor/glyphs/Flow.java | 11 ++++- .../items/armor/glyphs/Obfuscation.java | 10 ++++- .../items/armor/glyphs/Swiftness.java | 34 +++++++++++++- .../items/artifacts/DriedRose.java | 45 +++---------------- .../levels/features/HighGrass.java | 20 +-------- 16 files changed, 144 insertions(+), 253 deletions(-) diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java index 649b67e99..0031c9d55 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java @@ -96,8 +96,14 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.PrismaticImage; import com.shatteredpixel.shatteredpixeldungeon.effects.FloatingText; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle; import com.shatteredpixel.shatteredpixeldungeon.items.Heap; +import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor; +import com.shatteredpixel.shatteredpixeldungeon.items.armor.curses.Bulk; import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.AntiMagic; +import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Brimstone; +import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Flow; +import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Obfuscation; import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Potential; +import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Swiftness; import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Viscosity; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TimekeepersHourglass; @@ -680,6 +686,12 @@ public abstract class Char extends Actor { return damage; } + + //Returns the level a glyph is at for a char, or -1 if they are not benefitting from that glyph + //This function is needed as (unlike enchantments) many glyphs trigger in a variety of cases + public int glyphLevel(Class cls){ + return -1; + } public float speed() { float speed = baseSpeed; @@ -688,6 +700,11 @@ public abstract class Char extends Actor { if ( buff( Adrenaline.class ) != null) speed *= 2f; if ( buff( Haste.class ) != null) speed *= 3f; if ( buff( Dread.class ) != null) speed *= 2f; + + speed *= Swiftness.speedBoost(this, glyphLevel(Swiftness.class)); + speed *= Flow.speedBoost(this, glyphLevel(Flow.class)); + speed *= Bulk.speedBoost(this, glyphLevel(Bulk.class)); + return speed; } @@ -806,8 +823,11 @@ public abstract class Char extends Actor { } //TODO improve this when I have proper damage source logic - if (AntiMagic.RESISTS.contains(src.getClass()) && buff(ArcaneArmor.class) != null){ - dmg -= Random.NormalIntRange(0, buff(ArcaneArmor.class).level()); + if (AntiMagic.RESISTS.contains(src.getClass())){ + dmg -= AntiMagic.drRoll(this, glyphLevel(AntiMagic.class)); + if (buff(ArcaneArmor.class) != null) { + dmg -= Random.NormalIntRange(0, buff(ArcaneArmor.class).level()); + } if (dmg < 0) dmg = 0; } @@ -1112,7 +1132,11 @@ public abstract class Char extends Actor { } public float stealth() { - return 0; + float stealth = 0; + + stealth += Obfuscation.stealthBoost(this, glyphLevel(Obfuscation.class)); + + return stealth; } public final void move( int step ) { @@ -1203,6 +1227,9 @@ public abstract class Char extends Actor { for (Buff b : buffs()){ immunes.addAll(b.immunities()); } + if (glyphLevel(Brimstone.class) >= 0){ + immunes.add(Burning.class); + } for (Class c : immunes){ if (c.isAssignableFrom(effect)){ diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Burning.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Burning.java index 1c18b5893..f55bb897d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Burning.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/Burning.java @@ -180,11 +180,7 @@ public class Burning extends Buff implements Hero.Doom { public void reignite( Char ch, float duration ) { if (ch.isImmune(Burning.class)){ - //TODO this only works for the hero, not others who can have brimstone+arcana effect - // e.g. prismatic image, shadow clone - if (ch instanceof Hero - && ((Hero) ch).belongings.armor() != null - && ((Hero) ch).belongings.armor().hasGlyph(Brimstone.class, ch)){ + if (ch.glyphLevel(Brimstone.class) >= 0){ //generate avg of 1 shield per turn per 50% boost, to a max of 4x boost float shieldChance = 2*(Armor.Glyph.genericProcChanceMultiplier(ch) - 1f); int shieldCap = Math.round(shieldChance*4f); 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 8ef6e4805..ee1d8bfc2 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 @@ -42,7 +42,6 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Barrier; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Berserk; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Bless; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Charm; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Combo; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Drowsy; @@ -94,8 +93,6 @@ 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.glyphs.AntiMagic; -import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Brimstone; import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Viscosity; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.AlchemistsToolkit; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.CapeOfThorns; @@ -1515,7 +1512,16 @@ public class Hero extends Char { return super.defenseProc( enemy, damage ); } - + + @Override + public int glyphLevel(Class cls) { + if (belongings.armor() != null && belongings.armor().hasGlyph(cls, this)){ + return Math.max(super.glyphLevel(cls), belongings.armor.buffedLvl()); + } else { + return super.glyphLevel(cls); //TODO going to have recursion? + } + } + @Override public void damage( int dmg, Object src ) { if (buff(TimekeepersHourglass.timeStasis.class) != null @@ -1557,13 +1563,6 @@ public class Hero extends Char { dmg = (int)Math.ceil(dmg * RingOfTenacity.damageMultiplier( this )); - //TODO improve this when I have proper damage source logic - if (belongings.armor() != null && belongings.armor().hasGlyph(AntiMagic.class, this) - && AntiMagic.RESISTS.contains(src.getClass())){ - dmg -= AntiMagic.drRoll(this, belongings.armor().buffedLvl()); - dmg = Math.max(dmg, 0); - } - if (buff(Talent.WarriorFoodImmunity.class) != null){ if (pointsInTalent(Talent.IRON_STOMACH) == 1) dmg = Math.round(dmg*0.25f); else if (pointsInTalent(Talent.IRON_STOMACH) == 2) dmg = Math.round(dmg*0.00f); @@ -2049,17 +2048,6 @@ public class Hero extends Char { return false; } - @Override - public float stealth() { - float stealth = super.stealth(); - - if (belongings.armor() != null){ - stealth = belongings.armor().stealthFactor(this, stealth); - } - - return stealth; - } - @Override public void die( Object cause ) { @@ -2340,16 +2328,6 @@ public class Hero extends Char { } } - @Override - public boolean isImmune(Class effect) { - if (effect == Burning.class - && belongings.armor() != null - && belongings.armor().hasGlyph(Brimstone.class, this)){ - return true; - } - return super.isImmune(effect); - } - public boolean search( boolean intentional ) { if (!isAlive()) return false; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/rogue/ShadowClone.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/rogue/ShadowClone.java index cef802b17..c96e28001 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/rogue/ShadowClone.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/hero/abilities/rogue/ShadowClone.java @@ -26,7 +26,6 @@ import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.AllyBuff; -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass; @@ -35,9 +34,8 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbili import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.huntress.SpiritHawk; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.DirectableAlly; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.SmokeParticle; +import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor; import com.shatteredpixel.shatteredpixeldungeon.items.armor.ClassArmor; -import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.AntiMagic; -import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Brimstone; import com.shatteredpixel.shatteredpixeldungeon.levels.CityLevel; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; @@ -239,14 +237,12 @@ public class ShadowClone extends ArmorAbility { } @Override - public boolean isImmune(Class effect) { - if (effect == Burning.class - && Random.Int(4) < Dungeon.hero.pointsInTalent(Talent.CLONED_ARMOR) - && Dungeon.hero.belongings.armor() != null - && Dungeon.hero.belongings.armor().hasGlyph(Brimstone.class, this)){ - return true; + public int glyphLevel(Class cls) { + if (Random.Int(4) < Dungeon.hero.pointsInTalent(Talent.CLONED_ARMOR)){ + return Math.max(super.glyphLevel(cls), Dungeon.hero.glyphLevel(cls)); + } else { + return super.glyphLevel(cls); } - return super.isImmune(effect); } @Override @@ -260,21 +256,6 @@ public class ShadowClone extends ArmorAbility { } } - @Override - public void damage(int dmg, Object src) { - - //TODO improve this when I have proper damage source logic - if (Random.Int(4) < Dungeon.hero.pointsInTalent(Talent.CLONED_ARMOR) - && Dungeon.hero.belongings.armor() != null - && Dungeon.hero.belongings.armor().hasGlyph(AntiMagic.class, this) - && AntiMagic.RESISTS.contains(src.getClass())){ - dmg -= AntiMagic.drRoll(Dungeon.hero, Dungeon.hero.belongings.armor().buffedLvl()); - dmg = Math.max(dmg, 0); - } - - super.damage(dmg, src); - } - @Override public float speed() { float speed = super.speed(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/ArmoredStatue.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/ArmoredStatue.java index 1e8471181..0701a837c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/ArmoredStatue.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/ArmoredStatue.java @@ -23,12 +23,8 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.mobs; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; -import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning; import com.shatteredpixel.shatteredpixeldungeon.items.Generator; -import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor; -import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.AntiMagic; -import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Brimstone; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.sprites.CharSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.StatueSprite; @@ -83,16 +79,6 @@ public class ArmoredStatue extends Statue { return armor; } - @Override - public boolean isImmune(Class effect) { - if (effect == Burning.class - && armor != null - && armor.hasGlyph(Brimstone.class, this)){ - return true; - } - return super.isImmune(effect); - } - @Override public int defenseProc(Char enemy, int damage) { damage = armor.proc(enemy, this, damage); @@ -100,18 +86,12 @@ public class ArmoredStatue extends Statue { } @Override - public void damage(int dmg, Object src) { - //TODO improve this when I have proper damage source logic - if (armor != null && armor.hasGlyph(AntiMagic.class, this) - && AntiMagic.RESISTS.contains(src.getClass())){ - dmg -= AntiMagic.drRoll(this, armor.buffedLvl()); - dmg = Math.max(dmg, 0); + public int glyphLevel(Class cls) { + if (armor != null && armor.hasGlyph(cls, this)){ + return Math.max(super.glyphLevel(cls), armor.buffedLvl()); + } else { + return super.glyphLevel(cls); } - - super.damage( dmg, src ); - - //for the rose status indicator - Item.updateQuickslot(); } @Override @@ -125,16 +105,6 @@ public class ArmoredStatue extends Statue { return sprite; } - @Override - public float speed() { - return armor.speedFactor(this, super.speed()); - } - - @Override - public float stealth() { - return armor.stealthFactor(this, super.stealth()); - } - @Override public int defenseSkill(Char enemy) { return Math.round(armor.evasionFactor(this, super.defenseSkill(enemy))); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/PrismaticImage.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/PrismaticImage.java index 3ad759737..c71679248 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/PrismaticImage.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/npcs/PrismaticImage.java @@ -34,8 +34,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob; import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; -import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.AntiMagic; -import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Brimstone; +import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfAccuracy; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEvasion; import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm; @@ -202,28 +201,16 @@ public class PrismaticImage extends NPC { } return super.defenseProc(enemy, damage); } - + @Override - public void damage(int dmg, Object src) { - - //TODO improve this when I have proper damage source logic - if (hero != null && hero.belongings.armor() != null && hero.belongings.armor().hasGlyph(AntiMagic.class, this) - && AntiMagic.RESISTS.contains(src.getClass())){ - dmg -= AntiMagic.drRoll(hero, hero.belongings.armor().buffedLvl()); - dmg = Math.max(dmg, 0); + public int glyphLevel(Class cls) { + if (hero != null){ + return Math.max(super.glyphLevel(cls), hero.glyphLevel(cls)); + } else { + return super.glyphLevel(cls); } - - super.damage(dmg, src); } - - @Override - public float speed() { - if (hero != null && hero.belongings.armor() != null){ - return hero.belongings.armor().speedFactor(this, super.speed()); - } - return super.speed(); - } - + @Override public int attackProc( Char enemy, int damage ) { @@ -248,17 +235,6 @@ public class PrismaticImage extends NPC { return s; } - @Override - public boolean isImmune(Class effect) { - if (effect == Burning.class - && hero != null - && hero.belongings.armor() != null - && hero.belongings.armor().hasGlyph(Brimstone.class, this)){ - return true; - } - return super.isImmune(effect); - } - { immunities.add( ToxicGas.class ); immunities.add( CorrosiveGas.class ); 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 e2d2169f1..f3abb7753 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 @@ -24,7 +24,6 @@ package com.shatteredpixel.shatteredpixeldungeon.items.armor; import com.shatteredpixel.shatteredpixeldungeon.Badges; import com.shatteredpixel.shatteredpixeldungeon.Challenges; 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.MagicImmune; @@ -65,7 +64,6 @@ import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfArcana; import com.shatteredpixel.shatteredpixeldungeon.items.trinkets.ParchmentScrap; import com.shatteredpixel.shatteredpixeldungeon.items.trinkets.ShardOfOblivion; import com.shatteredpixel.shatteredpixeldungeon.journal.Catalog; -import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.sprites.HeroSprite; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; @@ -74,7 +72,6 @@ import com.shatteredpixel.shatteredpixeldungeon.utils.GLog; import com.watabou.noosa.particles.Emitter; import com.watabou.utils.Bundlable; import com.watabou.utils.Bundle; -import com.watabou.utils.PathFinder; import com.watabou.utils.Random; import com.watabou.utils.Reflection; @@ -373,48 +370,10 @@ public class Armor extends EquipableItem { if (aEnc > 0) speed /= Math.pow(1.2, aEnc); } - if (hasGlyph(Swiftness.class, owner)) { - boolean enemyNear = false; - //for each enemy, check if they are adjacent, or within 2 tiles and an adjacent cell is open - for (Char ch : Actor.chars()){ - if ( Dungeon.level.distance(ch.pos, owner.pos) <= 2 && owner.alignment != ch.alignment && ch.alignment != Char.Alignment.NEUTRAL){ - if (Dungeon.level.adjacent(ch.pos, owner.pos)){ - enemyNear = true; - break; - } else { - for (int i : PathFinder.NEIGHBOURS8){ - if (Dungeon.level.adjacent(owner.pos+i, ch.pos) && !Dungeon.level.solid[owner.pos+i]){ - enemyNear = true; - break; - } - } - } - } - } - if (!enemyNear) speed *= (1.2f + 0.04f * buffedLvl()) * glyph.procChanceMultiplier(owner); - } else if (hasGlyph(Flow.class, owner) && Dungeon.level.water[owner.pos]){ - speed *= (2f + 0.5f*buffedLvl()) * glyph.procChanceMultiplier(owner); - } - - if (hasGlyph(Bulk.class, owner) && - (Dungeon.level.map[owner.pos] == Terrain.DOOR - || Dungeon.level.map[owner.pos] == Terrain.OPEN_DOOR )) { - speed /= 3f * RingOfArcana.enchantPowerMultiplier(owner); - } - return speed; } - public float stealthFactor( Char owner, float stealth ){ - - if (hasGlyph(Obfuscation.class, owner)){ - stealth += (1 + buffedLvl()/3f) * glyph.procChanceMultiplier(owner); - } - - return stealth; - } - @Override public int level() { int level = super.level(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/curses/Bulk.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/curses/Bulk.java index d7ebd81fa..38e872c5c 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/curses/Bulk.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/curses/Bulk.java @@ -21,8 +21,10 @@ package com.shatteredpixel.shatteredpixeldungeon.items.armor.curses; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor; +import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; public class Bulk extends Armor.Glyph { @@ -31,10 +33,19 @@ public class Bulk extends Armor.Glyph { @Override public int proc(Armor armor, Char attacker, Char defender, int damage) { - - //no proc effect, see armor.speedfactor + //no proc effect, triggers in Char.speed() return damage; } + + //more of a reduction really + public static float speedBoost( Char owner, int level ){ + if (level == -1 || + (Dungeon.level.map[owner.pos] != Terrain.DOOR && Dungeon.level.map[owner.pos] != Terrain.OPEN_DOOR )) { + return 1; + } else { + return 1/3f * genericProcChanceMultiplier(owner); + } + } @Override public ItemSprite.Glowing glowing() { 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 26d47d321..7d755c5b8 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 @@ -134,19 +134,18 @@ public class AntiMagic extends Armor.Glyph { @Override public int proc(Armor armor, Char attacker, Char defender, int damage) { - //no proc effect, see: - // Hero.damage - // GhostHero.damage - // Shadowclone.damage - // ArmoredStatue.damage - // PrismaticImage.damage + //no proc effect, triggers in Char.damage return damage; } - public static int drRoll( Char ch, int level ){ - return Random.NormalIntRange( - Math.round(level * genericProcChanceMultiplier(ch)), - Math.round((3 + (level*1.5f)) * genericProcChanceMultiplier(ch))); + public static int drRoll( Char owner, int level ){ + if (level == -1){ + return 0; + } else { + return Random.NormalIntRange( + Math.round(level * genericProcChanceMultiplier(owner)), + Math.round((3 + (level * 1.5f)) * genericProcChanceMultiplier(owner))); + } } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Brimstone.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Brimstone.java index 75caa0808..74e39c165 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Brimstone.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Brimstone.java @@ -31,12 +31,7 @@ public class Brimstone extends Armor.Glyph { @Override public int proc(Armor armor, Char attacker, Char defender, int damage) { - //no proc effect, see: - // Hero.isImmune - // GhostHero.isImmune - // Shadowclone.isImmune - // ArmoredStatue.isImmune - // PrismaticImage.isImmune + //no proc effect, triggers in Char.isImmune return damage; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Camouflage.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Camouflage.java index f549fbaa3..b2b8c1180 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Camouflage.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Camouflage.java @@ -36,11 +36,12 @@ public class Camouflage extends Armor.Glyph { @Override public int proc(Armor armor, Char attacker, Char defender, int damage) { - //no proc effect, see HighGrass.trample + //no proc effect, triggers in HighGrass.trample return damage; } public static void activate(Char ch, int level){ + if (level == -1) return; Buff.prolong(ch, Invisibility.class, Math.round((3 + level/2f)* genericProcChanceMultiplier(ch))); if ( Dungeon.level.heroFOV[ch.pos] ) { Sample.INSTANCE.play( Assets.Sounds.MELD ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Flow.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Flow.java index 573a39501..29aaa94d3 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Flow.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Flow.java @@ -21,6 +21,7 @@ package com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; @@ -31,10 +32,18 @@ public class Flow extends Armor.Glyph { @Override public int proc(Armor armor, Char attacker, Char defender, int damage) { - //no proc effect, see armor.speedfactor for effect. + //no proc effect, triggers in Char.speed() return damage; } + public static float speedBoost( Char owner, int level ){ + if (level == -1 || !Dungeon.level.water[owner.pos]){ + return 1; + } else { + return (2f + 0.5f*level) * genericProcChanceMultiplier(owner); + } + } + @Override public ItemSprite.Glowing glowing() { return BLUE; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Obfuscation.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Obfuscation.java index a4e2f5594..83f2f7f72 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Obfuscation.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Obfuscation.java @@ -31,10 +31,18 @@ public class Obfuscation extends Armor.Glyph { @Override public int proc(Armor armor, Char attacker, Char defender, int damage) { - //no proc effect, see armor.stealthfactor for effect. + //no proc effect, triggered in Char.stealth() return damage; } + public static float stealthBoost( Char owner, int level ){ + if (level == -1) { + return 0; + } else { + return (1 + level / 3f) * genericProcChanceMultiplier(owner); + } + } + @Override public ItemSprite.Glowing glowing() { return GREY; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Swiftness.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Swiftness.java index f6aff27c5..2c616c20e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Swiftness.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/glyphs/Swiftness.java @@ -21,9 +21,12 @@ package com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs; +import com.shatteredpixel.shatteredpixeldungeon.Dungeon; +import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite; +import com.watabou.utils.PathFinder; public class Swiftness extends Armor.Glyph { @@ -31,10 +34,39 @@ public class Swiftness extends Armor.Glyph { @Override public int proc(Armor armor, Char attacker, Char defender, int damage) { - //no proc effect, see armor.speedfactor for effect. + //no proc effect, triggers in Char.speed() return damage; } + public static float speedBoost( Char owner, int level ){ + if (level == -1){ + return 1; + } + + boolean enemyNear = false; + //for each enemy, check if they are adjacent, or within 2 tiles and an adjacent cell is open + for (Char ch : Actor.chars()){ + if ( Dungeon.level.distance(ch.pos, owner.pos) <= 2 && owner.alignment != ch.alignment && ch.alignment != Char.Alignment.NEUTRAL){ + if (Dungeon.level.adjacent(ch.pos, owner.pos)){ + enemyNear = true; + break; + } else { + for (int i : PathFinder.NEIGHBOURS8){ + if (Dungeon.level.adjacent(owner.pos+i, ch.pos) && !Dungeon.level.solid[owner.pos+i]){ + enemyNear = true; + break; + } + } + } + } + } + if (enemyNear){ + return 1; + } else { + return (1.2f + 0.04f * level) * genericProcChanceMultiplier(owner); + } + } + @Override public ItemSprite.Glowing glowing() { return YELLOW; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/DriedRose.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/DriedRose.java index 431983978..28fedeb7a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/DriedRose.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/DriedRose.java @@ -45,8 +45,6 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShaftParticle; import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor; -import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.AntiMagic; -import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Brimstone; import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEnergy; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfRetribution; @@ -667,13 +665,6 @@ public class DriedRose extends Artifact { @Override public void damage(int dmg, Object src) { - //TODO improve this when I have proper damage source logic - if (rose != null && rose.armor != null && rose.armor.hasGlyph(AntiMagic.class, this) - && AntiMagic.RESISTS.contains(src.getClass())){ - dmg -= AntiMagic.drRoll(this, rose.armor.buffedLvl()); - dmg = Math.max(dmg, 0); - } - super.damage( dmg, src ); //for the rose status indicator @@ -683,10 +674,6 @@ public class DriedRose extends Artifact { @Override public float speed() { float speed = super.speed(); - - if (rose != null && rose.armor != null){ - speed = rose.armor.speedFactor(this, speed); - } //moves 2 tiles at a time when returning to the hero if (state == WANDERING @@ -709,17 +696,6 @@ public class DriedRose extends Artifact { return defense; } - @Override - public float stealth() { - float stealth = super.stealth(); - - if (rose != null && rose.armor != null){ - stealth = rose.armor.stealthFactor(this, stealth); - } - - return stealth; - } - @Override public int drRoll() { int dr = super.drRoll(); @@ -732,24 +708,13 @@ public class DriedRose extends Artifact { return dr; } - //used in some glyph calculations - public Armor armor(){ - if (rose != null){ - return rose.armor; - } else { - return null; - } - } - @Override - public boolean isImmune(Class effect) { - if (effect == Burning.class - && rose != null - && rose.armor != null - && rose.armor.hasGlyph(Brimstone.class, this)){ - return true; + public int glyphLevel(Class cls) { + if (rose != null && rose.armor != null && rose.armor.hasGlyph(cls, this)){ + return Math.max(super.glyphLevel(cls), rose.armor.buffedLvl()); + } else { + return super.glyphLevel(cls); } - return super.isImmune(effect); } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/features/HighGrass.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/features/HighGrass.java index bee53a6c5..e215d7470 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/features/HighGrass.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/features/HighGrass.java @@ -29,14 +29,12 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Talent; -import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.ArmoredStatue; import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith; import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.LeafParticle; import com.shatteredpixel.shatteredpixeldungeon.items.Dewdrop; import com.shatteredpixel.shatteredpixeldungeon.items.Generator; import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Camouflage; -import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose; import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.SandalsOfNature; import com.shatteredpixel.shatteredpixeldungeon.items.food.Berry; import com.shatteredpixel.shatteredpixeldungeon.items.trinkets.PetrifiedSeed; @@ -149,22 +147,8 @@ public class HighGrass { } } - //Camouflage - if (ch instanceof Hero) { - Hero hero = (Hero) ch; - if (hero.belongings.armor() != null && hero.belongings.armor().hasGlyph(Camouflage.class, hero)) { - Camouflage.activate(hero, hero.belongings.armor.buffedLvl()); - } - } else if (ch instanceof DriedRose.GhostHero){ - DriedRose.GhostHero ghost = (DriedRose.GhostHero) ch; - if (ghost.armor() != null && ghost.armor().hasGlyph(Camouflage.class, ghost)){ - Camouflage.activate(ghost, ghost.armor().buffedLvl()); - } - } else if (ch instanceof ArmoredStatue){ - ArmoredStatue statue = (ArmoredStatue) ch; - if (statue.armor() != null && statue.armor().hasGlyph(Camouflage.class, statue)){ - Camouflage.activate(statue, statue.armor().buffedLvl()); - } + if (ch != null) { + Camouflage.activate(ch, ch.glyphLevel(Camouflage.class)); } }