v0.6.5: overhauled glyphs and some armor interaction
- defenceproc how happens before DR reduction - antimagic now only works on magical effects specifically - entanglement roots are now delayed - potential no longer does self damage, charging adjusted - stone reworked, now exchanged evasion for defence - viscocity is now consistent - stone is now uncommon, viscocity is now common
This commit is contained in:
parent
55bb6e3121
commit
af7bf1e000
core/src/main
java/com/shatteredpixel/shatteredpixeldungeon
actors
items/armor
resources/com/shatteredpixel/shatteredpixeldungeon/messages/items
|
@ -45,12 +45,12 @@ public abstract class Actor implements Bundlable {
|
|||
//default priority values for general actor categories
|
||||
//note that some specific actors pick more specific values
|
||||
//e.g. a buff acting after all normal buffs might have priority BUFF_PRIO + 1
|
||||
protected final int VFX_PRIO = 100; //visual effects take priority
|
||||
protected final int HERO_PRIO = 0; //positive priority is before hero, negative after
|
||||
protected final int BLOB_PRIO = -10; //blobs act after hero, before mobs
|
||||
protected final int MOB_PRIO = -20; //mobs act between buffs and blobd
|
||||
protected final int BUFF_PRIO = -30; //buffs act last in a turn
|
||||
private final int DEFAULT = -100; //if no priority is given, act after all else
|
||||
protected static final int VFX_PRIO = 100; //visual effects take priority
|
||||
protected static final int HERO_PRIO = 0; //positive is before hero, negative after
|
||||
protected static final int BLOB_PRIO = -10; //blobs act after hero, before mobs
|
||||
protected static final int MOB_PRIO = -20; //mobs act between buffs and blobd
|
||||
protected static final int BUFF_PRIO = -30; //buffs act last in a turn
|
||||
private static final int DEFAULT = -100; //if no priority is given, act after all else
|
||||
|
||||
//used to determine what order actors act in if their time is equal. Higher values act earlier.
|
||||
protected int actPriority = DEFAULT;
|
||||
|
|
|
@ -180,11 +180,11 @@ public abstract class Char extends Actor {
|
|||
} else {
|
||||
dmg = damageRoll();
|
||||
}
|
||||
int effectiveDamage = Math.max( dmg - dr, 0 );
|
||||
|
||||
int effectiveDamage = enemy.defenseProc( this, dmg );
|
||||
effectiveDamage = Math.max( effectiveDamage - dr, 0 );
|
||||
effectiveDamage = attackProc( enemy, effectiveDamage );
|
||||
effectiveDamage = enemy.defenseProc( this, effectiveDamage );
|
||||
|
||||
|
||||
if (visibleFight) {
|
||||
Sample.INSTANCE.play( Assets.SND_HIT, 1, 1, Random.Float( 0.8f, 1.25f ) );
|
||||
}
|
||||
|
|
|
@ -234,10 +234,10 @@ public class Combo extends Buff implements ActionIndicator.Action {
|
|||
dmg = Math.round(dmg*0.6f);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
dmg = enemy.defenseProc(target, dmg);
|
||||
dmg -= enemy.drRoll();
|
||||
dmg = target.attackProc(enemy, dmg);
|
||||
dmg = enemy.defenseProc(target, dmg);
|
||||
enemy.damage( dmg, this );
|
||||
|
||||
//special effects
|
||||
|
|
|
@ -240,6 +240,7 @@ public class Belongings implements Iterable<Item> {
|
|||
|
||||
for (Wand.Charger charger : owner.buffs(Wand.Charger.class)){
|
||||
charger.gainCharge(charge);
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
|
|
|
@ -61,7 +61,6 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Heap.Type;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.KindOfWeapon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.AntiMagic;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Stone;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Viscosity;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.CapeOfThorns;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.DriedRose;
|
||||
|
@ -77,7 +76,6 @@ import com.shatteredpixel.shatteredpixeldungeon.items.keys.SkeletonKey;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfMight;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfStrength;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfElements;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEvasion;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfForce;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfFuror;
|
||||
|
@ -927,15 +925,15 @@ public class Hero extends Char {
|
|||
@Override
|
||||
public int defenseProc( Char enemy, int damage ) {
|
||||
|
||||
if (belongings.armor != null) {
|
||||
damage = belongings.armor.proc( enemy, this, damage );
|
||||
}
|
||||
|
||||
Earthroot.Armor armor = buff( Earthroot.Armor.class );
|
||||
if (armor != null) {
|
||||
damage = armor.absorb( damage );
|
||||
}
|
||||
|
||||
if (belongings.armor != null) {
|
||||
damage = belongings.armor.proc( enemy, this, damage );
|
||||
}
|
||||
|
||||
return damage;
|
||||
}
|
||||
|
||||
|
@ -963,7 +961,7 @@ public class Hero extends Char {
|
|||
|
||||
//TODO improve this when I have proper damage source logic
|
||||
if (belongings.armor != null && belongings.armor.hasGlyph(AntiMagic.class)
|
||||
&& RingOfElements.RESISTS.contains(src.getClass())){
|
||||
&& AntiMagic.RESISTS.contains(src.getClass())){
|
||||
dmg -= Random.NormalIntRange(belongings.armor.DRMin(), belongings.armor.DRMax())/3;
|
||||
}
|
||||
|
||||
|
@ -1090,19 +1088,13 @@ public class Hero extends Char {
|
|||
}
|
||||
|
||||
if (step != -1) {
|
||||
|
||||
int moveTime = 1;
|
||||
if (belongings.armor != null && belongings.armor.hasGlyph(Stone.class) &&
|
||||
(Dungeon.level.map[pos] == Terrain.DOOR
|
||||
|| Dungeon.level.map[pos] == Terrain.OPEN_DOOR
|
||||
|| Dungeon.level.map[step] == Terrain.DOOR
|
||||
|| Dungeon.level.map[step] == Terrain.OPEN_DOOR )){
|
||||
moveTime *= 2;
|
||||
}
|
||||
|
||||
float speed = speed();
|
||||
|
||||
sprite.move(pos, step);
|
||||
move(step);
|
||||
|
||||
spend( moveTime / speed() );
|
||||
spend( 1 / speed );
|
||||
|
||||
search(false);
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ package com.shatteredpixel.shatteredpixeldungeon.items.armor;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.Badges;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
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.Momentum;
|
||||
|
@ -269,6 +270,10 @@ public class Armor extends EquipableItem {
|
|||
|
||||
public float evasionFactor( Char owner, float evasion ){
|
||||
|
||||
if (hasGlyph(Stone.class) && !((Stone)glyph).testingEvasion()){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (owner instanceof Hero){
|
||||
int aEnc = STRReq() - ((Hero) owner).STR();
|
||||
if (aEnc > 0) evasion /= Math.pow(1.5, aEnc);
|
||||
|
@ -279,10 +284,6 @@ public class Armor extends EquipableItem {
|
|||
}
|
||||
}
|
||||
|
||||
if (hasGlyph(Swiftness.class)) {
|
||||
evasion += 5 + level()*1.5f;
|
||||
}
|
||||
|
||||
return evasion + augment.evasionFactor(level());
|
||||
}
|
||||
|
||||
|
@ -294,9 +295,16 @@ public class Armor extends EquipableItem {
|
|||
}
|
||||
|
||||
if (hasGlyph(Swiftness.class)) {
|
||||
speed *= (1.1f + 0.01f * level());
|
||||
boolean enemyNear = false;
|
||||
for (Char ch : Actor.chars()){
|
||||
if (Dungeon.level.adjacent(ch.pos, owner.pos) && owner.alignment != ch.alignment){
|
||||
enemyNear = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!enemyNear) speed *= (1.2f + 0.04f * level());
|
||||
} else if (hasGlyph(Flow.class) && Dungeon.level.water[owner.pos]){
|
||||
speed *= (1.5f + 0.05f * level());
|
||||
speed *= (1.5f + 0.1f * level());
|
||||
}
|
||||
|
||||
return speed;
|
||||
|
@ -506,8 +514,8 @@ public class Armor extends EquipableItem {
|
|||
public static abstract class Glyph implements Bundlable {
|
||||
|
||||
private static final Class<?>[] glyphs = new Class<?>[]{
|
||||
Obfuscation.class, Swiftness.class, Stone.class, Potential.class,
|
||||
Brimstone.class, Viscosity.class, Entanglement.class, Repulsion.class, Camouflage.class, Flow.class,
|
||||
Obfuscation.class, Swiftness.class, Viscosity.class, Potential.class,
|
||||
Brimstone.class, Stone.class, Entanglement.class, Repulsion.class, Camouflage.class, Flow.class,
|
||||
Affection.class, AntiMagic.class, Thorns.class };
|
||||
private static final float[] chances= new float[]{
|
||||
10, 10, 10, 10,
|
||||
|
|
|
@ -22,13 +22,37 @@
|
|||
package com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Charm;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Weakness;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Eye;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Shaman;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Warlock;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Yog;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.DisintegrationTrap;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.GrimTrap;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
public class AntiMagic extends Armor.Glyph {
|
||||
|
||||
private static ItemSprite.Glowing TEAL = new ItemSprite.Glowing( 0x88EEFF );
|
||||
|
||||
|
||||
public static final HashSet<Class> RESISTS = new HashSet<>();
|
||||
static {
|
||||
RESISTS.add( Charm.class );
|
||||
RESISTS.add( Weakness.class );
|
||||
|
||||
RESISTS.add( DisintegrationTrap.class );
|
||||
RESISTS.add( GrimTrap.class );
|
||||
|
||||
RESISTS.add( Shaman.class );
|
||||
RESISTS.add( Warlock.class );
|
||||
RESISTS.add( Eye.class );
|
||||
RESISTS.add( Yog.BurningFist.class );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int proc(Armor armor, Char attacker, Char defender, int damage) {
|
||||
//no proc effect, see Hero.damage
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs;
|
||||
|
||||
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.Roots;
|
||||
|
@ -32,6 +33,7 @@ import com.shatteredpixel.shatteredpixeldungeon.plants.Earthroot;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite.Glowing;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.utils.Bundle;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class Entanglement extends Glyph {
|
||||
|
@ -39,16 +41,39 @@ public class Entanglement extends Glyph {
|
|||
private static ItemSprite.Glowing BROWN = new ItemSprite.Glowing( 0x663300 );
|
||||
|
||||
@Override
|
||||
public int proc( Armor armor, Char attacker, Char defender, int damage ) {
|
||||
public int proc(Armor armor, Char attacker, final Char defender, final int damage ) {
|
||||
|
||||
int level = Math.max( 0, armor.level() );
|
||||
final int level = Math.max( 0, armor.level() );
|
||||
|
||||
final int pos = defender.pos;
|
||||
|
||||
if (Random.Int( 4 ) == 0) {
|
||||
|
||||
Buff.prolong( defender, Roots.class, 3 - level/5 );
|
||||
Buff.affect( defender, Earthroot.Armor.class ).level( 4 + 4*level );
|
||||
CellEmitter.bottom( defender.pos ).start( EarthParticle.FACTORY, 0.05f, 8 );
|
||||
Camera.main.shake( 1, 0.4f );
|
||||
Actor delay = new Actor() {
|
||||
|
||||
{
|
||||
actPriority = HERO_PRIO+1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean act() {
|
||||
|
||||
Buff.affect( defender, Earthroot.Armor.class ).level( 4 * (level + 1) );
|
||||
CellEmitter.bottom( defender.pos ).start( EarthParticle.FACTORY, 0.05f, 8 );
|
||||
Camera.main.shake( 1, 0.4f );
|
||||
|
||||
if (defender.buff(Roots.class) != null){
|
||||
Buff.prolong(defender, Roots.class, 5);
|
||||
} else {
|
||||
DelayedRoot root = Buff.append(defender, DelayedRoot.class);
|
||||
root.setup(pos);
|
||||
}
|
||||
|
||||
Actor.remove(this);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
Actor.addDelayed(delay, defender.cooldown());
|
||||
|
||||
}
|
||||
|
||||
|
@ -59,5 +84,42 @@ public class Entanglement extends Glyph {
|
|||
public Glowing glowing() {
|
||||
return BROWN;
|
||||
}
|
||||
|
||||
public static class DelayedRoot extends Buff{
|
||||
|
||||
{
|
||||
actPriority = HERO_PRIO-1;
|
||||
}
|
||||
|
||||
private int pos;
|
||||
|
||||
@Override
|
||||
public boolean act() {
|
||||
|
||||
if (target.pos == pos){
|
||||
Buff.prolong( target, Roots.class, 5 );
|
||||
}
|
||||
|
||||
detach();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setup( int pos ){
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
private static final String POS = "pos";
|
||||
|
||||
@Override
|
||||
public void restoreFromBundle(Bundle bundle) {
|
||||
super.restoreFromBundle(bundle);
|
||||
pos = bundle.getInt(POS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeInBundle(Bundle bundle) {
|
||||
super.storeInBundle(bundle);
|
||||
bundle.put(POS, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,15 +21,13 @@
|
|||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs;
|
||||
|
||||
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.Lightning;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.EnergyParticle;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor.Glyph;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite.Glowing;
|
||||
import com.watabou.noosa.Camera;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class Potential extends Glyph {
|
||||
|
||||
|
@ -39,21 +37,12 @@ public class Potential extends Glyph {
|
|||
public int proc( Armor armor, Char attacker, Char defender, int damage) {
|
||||
|
||||
int level = Math.max( 0, armor.level() );
|
||||
|
||||
if (Random.Int( level + 20 ) >= 18) {
|
||||
|
||||
int shockDmg = Random.NormalIntRange( 2, 6 );
|
||||
|
||||
defender.damage( shockDmg, this );
|
||||
|
||||
checkOwner( defender );
|
||||
if (defender == Dungeon.hero) {
|
||||
Dungeon.hero.belongings.charge(1f + level/10f);
|
||||
Camera.main.shake( 2, 0.3f );
|
||||
|
||||
if (defender instanceof Hero) {
|
||||
int wands = ((Hero) defender).belongings.charge(0.1f + level*0.05f);
|
||||
if (wands > 0) {
|
||||
defender.sprite.centerEmitter().burst(EnergyParticle.FACTORY, wands * (level + 2));
|
||||
}
|
||||
|
||||
attacker.sprite.parent.add( new Lightning( attacker.pos, defender.pos, null ) );
|
||||
|
||||
}
|
||||
|
||||
return damage;
|
||||
|
|
|
@ -32,8 +32,30 @@ public class Stone extends Armor.Glyph {
|
|||
@Override
|
||||
public int proc(Armor armor, Char attacker, Char defender, int damage) {
|
||||
//no proc effect, see armor.DrMin and the end of hero.getCloser
|
||||
|
||||
testing = true;
|
||||
float evasion = defender.defenseSkill(attacker);
|
||||
float accuracy = attacker.attackSkill(defender);
|
||||
testing = false;
|
||||
|
||||
float hitChance;
|
||||
if (evasion >= accuracy){
|
||||
hitChance = 1f - (1f - (accuracy/evasion))/2f;
|
||||
} else {
|
||||
hitChance = 1f - (evasion/accuracy)/2f;
|
||||
}
|
||||
|
||||
//FIXME this is probably very OP, needs balancing
|
||||
damage = (int)Math.ceil(damage * hitChance);
|
||||
|
||||
return damage;
|
||||
}
|
||||
|
||||
private boolean testing = false;
|
||||
|
||||
public boolean testingEvasion(){
|
||||
return testing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemSprite.Glowing glowing() {
|
||||
|
|
|
@ -34,7 +34,6 @@ import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite.Glowing;
|
|||
import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
|
||||
import com.watabou.utils.Bundle;
|
||||
import com.watabou.utils.Random;
|
||||
|
||||
public class Viscosity extends Glyph {
|
||||
|
||||
|
@ -49,22 +48,16 @@ public class Viscosity extends Glyph {
|
|||
|
||||
int level = Math.max( 0, armor.level() );
|
||||
|
||||
if (Random.Int( level + 6 ) >= 5) {
|
||||
|
||||
DeferedDamage debuff = defender.buff( DeferedDamage.class );
|
||||
if (debuff == null) {
|
||||
debuff = new DeferedDamage();
|
||||
debuff.attachTo( defender );
|
||||
}
|
||||
debuff.prolong( damage );
|
||||
|
||||
defender.sprite.showStatus( CharSprite.WARNING, Messages.get(this, "deferred", damage) );
|
||||
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
return damage;
|
||||
}
|
||||
float percent = (level+1)/(float)(level+6);
|
||||
int amount = (int)Math.ceil(damage * percent);
|
||||
|
||||
DeferedDamage deferred = Buff.affect( defender, DeferedDamage.class );
|
||||
deferred.prolong( amount );
|
||||
|
||||
defender.sprite.showStatus( CharSprite.WARNING, Messages.get(this, "deferred", amount) );
|
||||
|
||||
return damage - amount;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -32,7 +32,7 @@ items.armor.glyphs.camouflage.name=%s of camouflage
|
|||
items.armor.glyphs.camouflage.desc=This glyph allows the wearer to blend into tall grass, granting them temporary invisibility.
|
||||
|
||||
items.armor.glyphs.entanglement.name=%s of entanglement
|
||||
items.armor.glyphs.entanglement.desc=This glyph grows earthroot around the wearer to absorb damage, yet roots them in the process.
|
||||
items.armor.glyphs.entanglement.desc=This glyph grows earthroot around the wearer to absorb damage, but roots them if allowed to take hold.
|
||||
|
||||
items.armor.glyphs.flow.name=%s of flow
|
||||
items.armor.glyphs.flow.desc=This glyph manipulates the flow of water around the wearer, making them much faster when moving through it.
|
||||
|
@ -42,16 +42,16 @@ items.armor.glyphs.obfuscation.desc=This glyph obscures the wearer, making them
|
|||
|
||||
items.armor.glyphs.potential.name=%s of potential
|
||||
items.armor.glyphs.potential.rankings_desc=Killed by: glyph of potential
|
||||
items.armor.glyphs.potential.desc=This glyph releases energy when struck. This is harmful to the wearer, but recharges wands.
|
||||
items.armor.glyphs.potential.desc=This glyph builds energy when struck, giving a small amount of charge to the wearer's wands.
|
||||
|
||||
items.armor.glyphs.repulsion.name=%s of repulsion
|
||||
items.armor.glyphs.repulsion.desc=This glyph rebounds force against attackers, sending them flying back.
|
||||
|
||||
items.armor.glyphs.stone.name=%s of stone
|
||||
items.armor.glyphs.stone.desc=This glyph surrounds the armor with weightless magical stone that improves defense, but makes it difficult to fit through doorways.
|
||||
items.armor.glyphs.stone.desc=This glyph surrounds the armor with heavy magical stone that makes dodging impossible, but blocks damage in proportion with evasion.
|
||||
|
||||
items.armor.glyphs.swiftness.name=%s of swiftness
|
||||
items.armor.glyphs.swiftness.desc=This glyph alters the nature of armor, reducing weight and increasing evasion and speed, at the cost of defense.
|
||||
items.armor.glyphs.swiftness.desc=This glyph enhances the speed of the wearer whenever they aren't next to an enemy.
|
||||
|
||||
items.armor.glyphs.thorns.name=%s of thorns
|
||||
items.armor.glyphs.thorns.desc=This powerful glyph harms attackers, causing them to slowly bleed based on the damage they deal.
|
||||
|
|
Loading…
Reference in New Issue
Block a user