v0.7.0: significant magic immune implementation

This commit is contained in:
Evan Debenham 2018-07-21 17:29:09 -04:00
parent 83764f36d7
commit e436fd0ffa
12 changed files with 47 additions and 26 deletions

View File

@ -43,6 +43,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.FireImbue;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Frost; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Frost;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Haste; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Haste;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Hunger; 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.MagicalSleep;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Ooze; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Ooze;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Paralysis;
@ -355,6 +356,10 @@ public abstract class Char extends Actor {
if (buff( Paralysis.class ) != null) { if (buff( Paralysis.class ) != null) {
buff( Paralysis.class ).processDamage(dmg); buff( Paralysis.class ).processDamage(dmg);
} }
if (buff( MagicImmune.class ) != null && MagicImmune.IMMUNITIES.contains(src)){
dmg = 0;
}
int shielded = dmg; int shielded = dmg;
//FIXME: when I add proper damage properties, should add an IGNORES_SHIELDS property to use here. //FIXME: when I add proper damage properties, should add an IGNORES_SHIELDS property to use here.

View File

@ -86,11 +86,12 @@ public class Burning extends Buff implements Hero.Doom {
int damage = Random.NormalIntRange( 1, 3 + target.HT/40 ); int damage = Random.NormalIntRange( 1, 3 + target.HT/40 );
Buff.detach( target, Chill.class); Buff.detach( target, Chill.class);
//FIXME doesn't work with the sad ghost
if (target instanceof Hero) { if (target instanceof Hero) {
Hero hero = (Hero)target; 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); Buff.affect(target, Brimstone.BrimstoneShield.class);
} else { } else {

View File

@ -21,16 +21,23 @@
package com.shatteredpixel.shatteredpixeldungeon.actors.buffs; package com.shatteredpixel.shatteredpixeldungeon.actors.buffs;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.AntiMagic;
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator; import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
import java.util.HashSet;
public class MagicImmune extends FlavourBuff { public class MagicImmune extends FlavourBuff {
public static final HashSet<Class> IMMUNITIES = (HashSet<Class>) AntiMagic.RESISTS.clone();
//TODO visuals //TODO visuals
//FIXME this does not currently handle all cases, need to implement: //FIXME this does not currently handle all cases, need to implement:
//- all glyph effects not working //+ all enchant effects not working
//- equipped curse being removable //+ all glyph effects not working
//- 0 damage from magical attacks //+ equipped curse being removable
//+ 0 damage from magical attacks
//- text for all of these //- text for all of these
//what about active buffs/debuffs? //what about active buffs/debuffs?

View File

@ -980,7 +980,7 @@ public class Hero extends Char {
dmg = (int)Math.ceil(dmg * RingOfTenacity.damageMultiplier( this )); dmg = (int)Math.ceil(dmg * RingOfTenacity.damageMultiplier( this ));
//TODO improve this when I have proper damage source logic //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())){ && AntiMagic.RESISTS.contains(src.getClass())){
dmg -= Random.NormalIntRange(belongings.armor.DRMin(), belongings.armor.DRMax())/3; dmg -= Random.NormalIntRange(belongings.armor.DRMin(), belongings.armor.DRMax())/3;
} }

View File

@ -24,6 +24,7 @@ package com.shatteredpixel.shatteredpixeldungeon.items;
import com.shatteredpixel.shatteredpixeldungeon.Assets; import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicImmune;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle; import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; 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 ) { 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")); GLog.w(Messages.get(EquipableItem.class, "unequip_cursed"));
return false; return false;
} }

View File

@ -27,6 +27,7 @@ import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff; 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.buffs.Momentum;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck; import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
@ -274,7 +275,7 @@ public class Armor extends EquipableItem {
public float evasionFactor( Char owner, float evasion ){ public float evasionFactor( Char owner, float evasion ){
if (hasGlyph(Stone.class) && !((Stone)glyph).testingEvasion()){ if (hasGlyph(Stone.class, owner) && !((Stone)glyph).testingEvasion()){
return 0; return 0;
} }
@ -298,7 +299,7 @@ public class Armor extends EquipableItem {
if (aEnc > 0) speed /= Math.pow(1.2, aEnc); if (aEnc > 0) speed /= Math.pow(1.2, aEnc);
} }
if (hasGlyph(Swiftness.class)) { if (hasGlyph(Swiftness.class, owner)) {
boolean enemyNear = false; boolean enemyNear = false;
for (Char ch : Actor.chars()){ for (Char ch : Actor.chars()){
if (Dungeon.level.adjacent(ch.pos, owner.pos) && owner.alignment != ch.alignment){ 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()); 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()); 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.DOOR
|| Dungeon.level.map[owner.pos] == Terrain.OPEN_DOOR )) { || Dungeon.level.map[owner.pos] == Terrain.OPEN_DOOR )) {
speed /= 3f; speed /= 3f;
@ -323,7 +324,7 @@ public class Armor extends EquipableItem {
public float stealthFactor( Char owner, float stealth ){ public float stealthFactor( Char owner, float stealth ){
if (hasGlyph(Obfuscation.class)){ if (hasGlyph(Obfuscation.class, owner)){
stealth += 1 + level()/3f; stealth += 1 + level()/3f;
} }
@ -353,7 +354,7 @@ public class Armor extends EquipableItem {
public int proc( Char attacker, Char defender, int damage ) { 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 ); damage = glyph.proc( this, attacker, defender, damage );
} }
@ -505,10 +506,11 @@ public class Armor extends EquipableItem {
return inscribe( gl ); return inscribe( gl );
} }
public boolean hasGlyph(Class<?extends Glyph> type) { public boolean hasGlyph(Class<?extends Glyph> type, Char owner) {
return glyph != null && glyph.getClass() == type; 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(){ public boolean hasGoodGlyph(){
return glyph != null && !glyph.curse(); return glyph != null && !glyph.curse();
} }

View File

@ -44,6 +44,7 @@ public class Brimstone extends Armor.Glyph {
return ORANGE; return ORANGE;
} }
//FIXME doesn't work with sad ghost
public static class BrimstoneShield extends ShieldBuff { public static class BrimstoneShield extends ShieldBuff {
{ {
@ -54,7 +55,7 @@ public class Brimstone extends Armor.Glyph {
public boolean act() { public boolean act() {
Hero hero = (Hero)target; 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(); detach();
return true; return true;
} }

View File

@ -536,7 +536,7 @@ public class DriedRose extends Artifact {
@Override @Override
public void damage(int dmg, Object src) { public void damage(int dmg, Object src) {
//TODO improve this when I have proper damage source logic //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())){ && RingOfElements.RESISTS.contains(src.getClass())){
dmg -= Random.NormalIntRange(rose.armor.DRMin(), rose.armor.DRMax())/3; dmg -= Random.NormalIntRange(rose.armor.DRMin(), rose.armor.DRMax())/3;
} }

View File

@ -150,7 +150,7 @@ abstract public class Weapon extends KindOfWeapon {
encumbrance = STRReq() - ((Hero)owner).STR(); encumbrance = STRReq() - ((Hero)owner).STR();
} }
if (hasEnchant(Wayward.class)) if (hasEnchant(Wayward.class, owner))
encumbrance = Math.max(2, encumbrance+2); encumbrance = Math.max(2, encumbrance+2);
float ACC = this.ACC; float ACC = this.ACC;
@ -175,7 +175,7 @@ abstract public class Weapon extends KindOfWeapon {
@Override @Override
public int reachFactor(Char owner) { public int reachFactor(Char owner) {
return hasEnchant(Projecting.class) ? RCH+1 : RCH; return hasEnchant(Projecting.class, owner) ? RCH+1 : RCH;
} }
public int STRReq(){ public int STRReq(){
@ -250,15 +250,17 @@ abstract public class Weapon extends KindOfWeapon {
return enchant( ench ); return enchant( ench );
} }
public boolean hasEnchant(Class<?extends Enchantment> type) { public boolean hasEnchant(Class<?extends Enchantment> type, Char owner) {
return enchantment != null && enchantment.getClass() == type; 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(){ public boolean hasGoodEnchant(){
return enchantment != null && !enchantment.curse(); return enchantment != null && !enchantment.curse();
} }
public boolean hasCurseEnchant(){ return enchantment != null && enchantment.curse(); public boolean hasCurseEnchant(){
return enchantment != null && enchantment.curse();
} }
@Override @Override

View File

@ -77,7 +77,7 @@ abstract public class MissileWeapon extends Weapon {
@Override @Override
public int throwPos(Hero user, int dst) { 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){ && !Dungeon.level.solid[dst] && Dungeon.level.distance(user.pos, dst) <= 4){
return dst; return dst;
} else { } else {

View File

@ -23,6 +23,7 @@ package com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.darts;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.MagicImmune;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero; import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Projecting; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Projecting;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Crossbow; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.Crossbow;
@ -67,7 +68,7 @@ public class Dart extends MissileWeapon {
@Override @Override
public int throwPos(Hero user, int dst) { 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){ && !Dungeon.level.solid[dst] && Dungeon.level.distance(user.pos, dst) <= 4){
return dst; return dst;
} else { } else {
@ -77,7 +78,7 @@ public class Dart extends MissileWeapon {
@Override @Override
public int proc(Char attacker, Char defender, int damage) { 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); damage = bow.enchantment.proc(bow, attacker, defender, damage);
} }
return super.proc(attacker, defender, damage); return super.proc(attacker, defender, damage);

View File

@ -94,7 +94,8 @@ public class HighGrass {
} }
//Camouflage //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()); Buff.affect(hero, Camouflage.Camo.class).set(3 + hero.belongings.armor.level());
leaves += 4; leaves += 4;
} }