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 f7d04e10f..761416d88 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/Char.java @@ -43,6 +43,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FireImbue; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Frost; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Haste; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Hunger; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicImmune; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicalSleep; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Ooze; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis; @@ -355,6 +356,10 @@ public abstract class Char extends Actor { if (buff( Paralysis.class ) != null) { buff( Paralysis.class ).processDamage(dmg); } + + if (buff( MagicImmune.class ) != null && MagicImmune.IMMUNITIES.contains(src)){ + dmg = 0; + } int shielded = dmg; //FIXME: when I add proper damage properties, should add an IGNORES_SHIELDS property to use here. 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 e421bb04b..69ae27877 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 @@ -86,11 +86,12 @@ public class Burning extends Buff implements Hero.Doom { int damage = Random.NormalIntRange( 1, 3 + target.HT/40 ); Buff.detach( target, Chill.class); + //FIXME doesn't work with the sad ghost if (target instanceof Hero) { Hero hero = (Hero)target; - if (hero.belongings.armor != null && hero.belongings.armor.hasGlyph(Brimstone.class)){ + if (hero.belongings.armor != null && hero.belongings.armor.hasGlyph(Brimstone.class, hero)){ Buff.affect(target, Brimstone.BrimstoneShield.class); } else { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/MagicImmune.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/MagicImmune.java index fc5934832..8499db77a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/MagicImmune.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/buffs/MagicImmune.java @@ -21,16 +21,23 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.buffs; +import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.AntiMagic; import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator; +import java.util.HashSet; + public class MagicImmune extends FlavourBuff { + + public static final HashSet IMMUNITIES = (HashSet) AntiMagic.RESISTS.clone(); + //TODO visuals //FIXME this does not currently handle all cases, need to implement: - //- all glyph effects not working - //- equipped curse being removable - //- 0 damage from magical attacks + //+ all enchant effects not working + //+ all glyph effects not working + //+ equipped curse being removable + //+ 0 damage from magical attacks //- text for all of these //what about active buffs/debuffs? 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 7b4419da2..d237c44c7 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 @@ -980,7 +980,7 @@ 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) + if (belongings.armor != null && belongings.armor.hasGlyph(AntiMagic.class, this) && AntiMagic.RESISTS.contains(src.getClass())){ dmg -= Random.NormalIntRange(belongings.armor.DRMin(), belongings.armor.DRMax())/3; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/EquipableItem.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/EquipableItem.java index 89c682bc0..23c35ac1d 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/EquipableItem.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/EquipableItem.java @@ -24,6 +24,7 @@ package com.shatteredpixel.shatteredpixeldungeon.items; import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicImmune; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; @@ -99,7 +100,7 @@ public abstract class EquipableItem extends Item { public boolean doUnequip( Hero hero, boolean collect, boolean single ) { - if (cursed) { + if (cursed && hero.buff(MagicImmune.class) == null) { GLog.w(Messages.get(EquipableItem.class, "unequip_cursed")); return false; } 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 a7a45ff85..c91d9357b 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 @@ -27,6 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; 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; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Momentum; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; @@ -274,7 +275,7 @@ public class Armor extends EquipableItem { public float evasionFactor( Char owner, float evasion ){ - if (hasGlyph(Stone.class) && !((Stone)glyph).testingEvasion()){ + if (hasGlyph(Stone.class, owner) && !((Stone)glyph).testingEvasion()){ return 0; } @@ -298,7 +299,7 @@ public class Armor extends EquipableItem { if (aEnc > 0) speed /= Math.pow(1.2, aEnc); } - if (hasGlyph(Swiftness.class)) { + if (hasGlyph(Swiftness.class, owner)) { boolean enemyNear = false; for (Char ch : Actor.chars()){ if (Dungeon.level.adjacent(ch.pos, owner.pos) && owner.alignment != ch.alignment){ @@ -307,11 +308,11 @@ public class Armor extends EquipableItem { } } if (!enemyNear) speed *= (1.2f + 0.04f * level()); - } else if (hasGlyph(Flow.class) && Dungeon.level.water[owner.pos]){ + } else if (hasGlyph(Flow.class, owner) && Dungeon.level.water[owner.pos]){ speed *= (1.5f + 0.1f * level()); } - if (hasGlyph(Bulk.class) && + if (hasGlyph(Bulk.class, owner) && (Dungeon.level.map[owner.pos] == Terrain.DOOR || Dungeon.level.map[owner.pos] == Terrain.OPEN_DOOR )) { speed /= 3f; @@ -323,7 +324,7 @@ public class Armor extends EquipableItem { public float stealthFactor( Char owner, float stealth ){ - if (hasGlyph(Obfuscation.class)){ + if (hasGlyph(Obfuscation.class, owner)){ stealth += 1 + level()/3f; } @@ -353,7 +354,7 @@ public class Armor extends EquipableItem { public int proc( Char attacker, Char defender, int damage ) { - if (glyph != null) { + if (glyph != null && defender.buff(MagicImmune.class) != null) { damage = glyph.proc( this, attacker, defender, damage ); } @@ -505,10 +506,11 @@ public class Armor extends EquipableItem { return inscribe( gl ); } - public boolean hasGlyph(Class type) { - return glyph != null && glyph.getClass() == type; + public boolean hasGlyph(Class type, Char owner) { + return glyph != null && glyph.getClass() == type && owner.buff(MagicImmune.class) == null; } + //these are not used to process specific glyph effects, so magic immune doesn't affect them public boolean hasGoodGlyph(){ return glyph != null && !glyph.curse(); } 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 21a57548e..ef93725df 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 @@ -44,6 +44,7 @@ public class Brimstone extends Armor.Glyph { return ORANGE; } + //FIXME doesn't work with sad ghost public static class BrimstoneShield extends ShieldBuff { { @@ -54,7 +55,7 @@ public class Brimstone extends Armor.Glyph { public boolean act() { Hero hero = (Hero)target; - if (hero.belongings.armor == null || !hero.belongings.armor.hasGlyph(Brimstone.class)) { + if (hero.belongings.armor == null || !hero.belongings.armor.hasGlyph(Brimstone.class, hero)) { detach(); return true; } 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 92c7b194b..5eb90679a 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 @@ -536,7 +536,7 @@ 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) + if (rose != null && rose.armor != null && rose.armor.hasGlyph(AntiMagic.class, this) && RingOfElements.RESISTS.contains(src.getClass())){ dmg -= Random.NormalIntRange(rose.armor.DRMin(), rose.armor.DRMax())/3; } 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 400107220..7d805c931 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 @@ -150,7 +150,7 @@ abstract public class Weapon extends KindOfWeapon { encumbrance = STRReq() - ((Hero)owner).STR(); } - if (hasEnchant(Wayward.class)) + if (hasEnchant(Wayward.class, owner)) encumbrance = Math.max(2, encumbrance+2); float ACC = this.ACC; @@ -175,7 +175,7 @@ abstract public class Weapon extends KindOfWeapon { @Override public int reachFactor(Char owner) { - return hasEnchant(Projecting.class) ? RCH+1 : RCH; + return hasEnchant(Projecting.class, owner) ? RCH+1 : RCH; } public int STRReq(){ @@ -250,15 +250,17 @@ abstract public class Weapon extends KindOfWeapon { return enchant( ench ); } - public boolean hasEnchant(Class type) { - return enchantment != null && enchantment.getClass() == type; + public boolean hasEnchant(Class type, Char owner) { + return enchantment != null && enchantment.getClass() == type && owner.buff(MagicImmune.class) != null; } - + + //these are not used to process specific enchant effects, so magic immune doesn't affect them public boolean hasGoodEnchant(){ return enchantment != null && !enchantment.curse(); } - public boolean hasCurseEnchant(){ return enchantment != null && enchantment.curse(); + public boolean hasCurseEnchant(){ + return enchantment != null && enchantment.curse(); } @Override diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/MissileWeapon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/MissileWeapon.java index 18319688b..666130949 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/MissileWeapon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/MissileWeapon.java @@ -77,7 +77,7 @@ abstract public class MissileWeapon extends Weapon { @Override public int throwPos(Hero user, int dst) { - if (hasEnchant(Projecting.class) + if (hasEnchant(Projecting.class, user) && !Dungeon.level.solid[dst] && Dungeon.level.distance(user.pos, dst) <= 4){ return dst; } else { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/Dart.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/Dart.java index ec71f6fff..f1f684bce 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/Dart.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/Dart.java @@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.darts; import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.actors.Char; +import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicImmune; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Projecting; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Crossbow; @@ -67,7 +68,7 @@ public class Dart extends MissileWeapon { @Override public int throwPos(Hero user, int dst) { - if (bow != null && bow.hasEnchant(Projecting.class) + if (bow != null && bow.hasEnchant(Projecting.class, user) && !Dungeon.level.solid[dst] && Dungeon.level.distance(user.pos, dst) <= 4){ return dst; } else { @@ -77,7 +78,7 @@ public class Dart extends MissileWeapon { @Override public int proc(Char attacker, Char defender, int damage) { - if (bow != null && bow.enchantment != null){ + if (bow != null && bow.enchantment != null && attacker.buff(MagicImmune.class) != null){ damage = bow.enchantment.proc(bow, attacker, defender, damage); } return super.proc(attacker, defender, damage); 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 6e0ad8b2e..11e27f47b 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 @@ -94,7 +94,8 @@ public class HighGrass { } //Camouflage - if (hero.belongings.armor != null && hero.belongings.armor.hasGlyph(Camouflage.class)){ + //FIXME doesn't work with sad ghost + if (hero.belongings.armor != null && hero.belongings.armor.hasGlyph(Camouflage.class, hero)){ Buff.affect(hero, Camouflage.Camo.class).set(3 + hero.belongings.armor.level()); leaves += 4; }