v3.0.0: substantially improved code for non-proc glyph fx

This commit is contained in:
Evan Debenham
2025-01-20 12:00:47 -05:00
parent d2320e93fd
commit d556f966cc
16 changed files with 144 additions and 253 deletions

View File

@@ -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<? extends Armor.Glyph> 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)){

View File

@@ -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);

View File

@@ -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<? extends Armor.Glyph> 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;

View File

@@ -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<? extends Armor.Glyph> 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();

View File

@@ -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<? extends Armor.Glyph> 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)));

View File

@@ -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<? extends Armor.Glyph> 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 );

View File

@@ -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();

View File

@@ -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() {

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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 );

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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<? extends Armor.Glyph> 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

View File

@@ -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));
}
}