v0.4.0: lots more curse implementation

This commit is contained in:
Evan Debenham 2016-06-09 08:58:58 -04:00 committed by Evan Debenham
parent 909e3bc445
commit b8f6881830
12 changed files with 240 additions and 46 deletions

View File

@ -46,13 +46,13 @@ import java.util.HashMap;
public class Generator { public class Generator {
public static enum Category { public static enum Category {
WEAPON ( 150, Weapon.class ), WEAPON ( 100, Weapon.class ),
WEP_T1 ( 0, Weapon.class), WEP_T1 ( 0, Weapon.class),
WEP_T2 ( 0, Weapon.class), WEP_T2 ( 0, Weapon.class),
WEP_T3 ( 0, Weapon.class), WEP_T3 ( 0, Weapon.class),
WEP_T4 ( 0, Weapon.class), WEP_T4 ( 0, Weapon.class),
WEP_T5 ( 0, Weapon.class), WEP_T5 ( 0, Weapon.class),
ARMOR ( 100, Armor.class ), ARMOR ( 60, Armor.class ),
POTION ( 500, Potion.class ), POTION ( 500, Potion.class ),
SCROLL ( 400, Scroll.class ), SCROLL ( 400, Scroll.class ),
WAND ( 40, Wand.class ), WAND ( 40, Wand.class ),

View File

@ -31,6 +31,9 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.particles.ShadowParticle
import com.shatteredpixel.shatteredpixeldungeon.items.BrokenSeal; import com.shatteredpixel.shatteredpixeldungeon.items.BrokenSeal;
import com.shatteredpixel.shatteredpixeldungeon.items.EquipableItem; import com.shatteredpixel.shatteredpixeldungeon.items.EquipableItem;
import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.curses.AntiEntropy;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.curses.Displacement;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.curses.Metabolism;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.curses.Stench; import com.shatteredpixel.shatteredpixeldungeon.items.armor.curses.Stench;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Affection; import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.Affection;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.AntiMagic; import com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs.AntiMagic;
@ -422,7 +425,7 @@ public class Armor extends EquipableItem {
2, 2, 2 }; 2, 2, 2 };
private static final Class<?>[] curses = new Class<?>[]{ private static final Class<?>[] curses = new Class<?>[]{
Stench.class AntiEntropy.class, Displacement.class, Metabolism.class, Stench.class
}; };
public abstract int proc( Armor armor, Char attacker, Char defender, int damage ); public abstract int proc( Armor armor, Char attacker, Char defender, int damage );

View File

@ -18,7 +18,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> * along with this program. If not, see <http://www.gnu.org/licenses/>
*/ */
package com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs; package com.shatteredpixel.shatteredpixeldungeon.items.armor.curses;
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;
@ -35,18 +35,18 @@ import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite.Glowing;
import com.watabou.utils.Random; import com.watabou.utils.Random;
public class AntiEntropy extends Glyph { public class AntiEntropy extends Glyph {
private static ItemSprite.Glowing BLUE = new ItemSprite.Glowing( 0x0000FF ); private static ItemSprite.Glowing BLACK = new ItemSprite.Glowing( 0x000000 );
@Override @Override
public int proc( Armor armor, Char attacker, Char defender, int damage) { public int proc( Armor armor, Char attacker, Char defender, int damage) {
int level = Math.max( 0, armor.level() ); if (Random.Int( 8 ) == 0) {
if (Level.adjacent( attacker.pos, defender.pos ) && Random.Int( level + 6 ) >= 5) { if (Level.adjacent( attacker.pos, defender.pos )) {
Buff.prolong(attacker, Frost.class, Frost.duration(attacker) * Random.Float(0.5f, 1f));
Buff.prolong( attacker, Frost.class, Frost.duration( attacker ) * Random.Float( 1f, 1.5f )); CellEmitter.get(attacker.pos).start(SnowParticle.FACTORY, 0.2f, 6);
CellEmitter.get( attacker.pos ).start( SnowParticle.FACTORY, 0.2f, 6 ); }
Buff.affect( defender, Burning.class ).reignite( defender ); Buff.affect( defender, Burning.class ).reignite( defender );
defender.sprite.emitter().burst( FlameParticle.FACTORY, 5 ); defender.sprite.emitter().burst( FlameParticle.FACTORY, 5 );
@ -58,6 +58,11 @@ public class AntiEntropy extends Glyph {
@Override @Override
public Glowing glowing() { public Glowing glowing() {
return BLUE; return BLACK;
}
@Override
public boolean curse() {
return true;
} }
} }

View File

@ -0,0 +1,54 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
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.items.scrolls.ScrollOfTeleportation;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.watabou.utils.Random;
public class Displacement extends Armor.Glyph {
private static ItemSprite.Glowing BLACK = new ItemSprite.Glowing( 0x000000 );
@Override
public int proc(Armor armor, Char attacker, Char defender, int damage ) {
if (defender == Dungeon.hero && Random.Int(20) == 0){
ScrollOfTeleportation.teleportHero(Dungeon.hero);
return 0;
}
return damage;
}
@Override
public ItemSprite.Glowing glowing() {
return BLACK;
}
@Override
public boolean curse() {
return true;
}
}

View File

@ -18,7 +18,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> * along with this program. If not, see <http://www.gnu.org/licenses/>
*/ */
package com.shatteredpixel.shatteredpixeldungeon.items.armor.glyphs; package com.shatteredpixel.shatteredpixeldungeon.items.armor.curses;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Hunger; import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Hunger;
@ -32,16 +32,16 @@ import com.shatteredpixel.shatteredpixeldungeon.ui.BuffIndicator;
import com.watabou.utils.Random; import com.watabou.utils.Random;
public class Metabolism extends Glyph { public class Metabolism extends Glyph {
private static ItemSprite.Glowing RED = new ItemSprite.Glowing( 0xCC0000 ); private static ItemSprite.Glowing BLACK = new ItemSprite.Glowing( 0x000000 );
@Override @Override
public int proc( Armor armor, Char attacker, Char defender, int damage) { public int proc( Armor armor, Char attacker, Char defender, int damage) {
int level = Math.max( 0, armor.level() ); if (Random.Int( 6 ) == 0) {
if (Random.Int( level / 2 + 5 ) >= 4) {
//assumes using up 10% of starving, and healing of 1 hp per 10 turns;
int healing = Math.min( defender.HT - defender.HP, Random.Int( 1, defender.HT / 5 ) ); int healing = Math.min((int)Hunger.STARVING/100, defender.HT - defender.HP);
if (healing > 0) { if (healing > 0) {
@ -49,7 +49,7 @@ public class Metabolism extends Glyph {
if (hunger != null && !hunger.isStarving()) { if (hunger != null && !hunger.isStarving()) {
hunger.reduceHunger( -Hunger.STARVING / 10 ); hunger.reduceHunger( healing * -10 );
BuffIndicator.refreshHero(); BuffIndicator.refreshHero();
defender.HP += healing; defender.HP += healing;
@ -65,6 +65,11 @@ public class Metabolism extends Glyph {
@Override @Override
public Glowing glowing() { public Glowing glowing() {
return RED; return BLACK;
}
@Override
public boolean curse() {
return true;
} }
} }

View File

@ -35,7 +35,7 @@ public class Stench extends Armor.Glyph {
@Override @Override
public int proc(Armor armor, Char attacker, Char defender, int damage) { public int proc(Armor armor, Char attacker, Char defender, int damage) {
if ( Random.Int( 6 ) == 0) { if ( Random.Int( 8 ) == 0) {
GameScene.add( Blob.seed( attacker.pos, 250, ToxicGas.class ) ); GameScene.add( Blob.seed( attacker.pos, 250, ToxicGas.class ) );

View File

@ -31,6 +31,8 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.KindOfWeapon; import com.shatteredpixel.shatteredpixeldungeon.items.KindOfWeapon;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfFuror; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfFuror;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfSharpshooting; import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfSharpshooting;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.curses.Annoying;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.curses.Exhausting;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.curses.Fragile; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.curses.Fragile;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.curses.Wayward; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.curses.Wayward;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Blazing; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Blazing;
@ -274,7 +276,7 @@ abstract public class Weapon extends KindOfWeapon {
2, 2, 2 }; 2, 2, 2 };
private static final Class<?>[] curses = new Class<?>[]{ private static final Class<?>[] curses = new Class<?>[]{
Fragile.class, Wayward.class Annoying.class, Exhausting.class, Fragile.class, Wayward.class
}; };
public abstract int proc( Weapon weapon, Char attacker, Char defender, int damage ); public abstract int proc( Weapon weapon, Char attacker, Char defender, int damage );

View File

@ -0,0 +1,66 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.items.weapon.curses;
import com.shatteredpixel.shatteredpixeldungeon.Assets;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Invisibility;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Mob;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Random;
public class Annoying extends Weapon.Enchantment {
private static ItemSprite.Glowing BLACK = new ItemSprite.Glowing( 0x000000 );
@Override
public int proc( Weapon weapon, Char attacker, Char defender, int damage ) {
if (Random.Int(20) == 0) {
for (Mob mob : Dungeon.level.mobs.toArray(new Mob[0])) {
mob.beckon(attacker.pos);
}
attacker.sprite.centerEmitter().start(Speck.factory(Speck.SCREAM), 0.3f, 3);
Sample.INSTANCE.play(Assets.SND_MIMIC);
Invisibility.dispel();
GLog.n(Messages.get(this, "msg_" + (Random.Int(5)+1)));
}
return damage;
}
@Override
public boolean curse() {
return true;
}
@Override
public ItemSprite.Glowing glowing() {
return BLACK;
}
}

View File

@ -0,0 +1,54 @@
/*
* Pixel Dungeon
* Copyright (C) 2012-2015 Oleg Dolya
*
* Shattered Pixel Dungeon
* Copyright (C) 2014-2016 Evan Debenham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.items.weapon.curses;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Weakness;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.watabou.utils.Random;
public class Exhausting extends Weapon.Enchantment {
private static ItemSprite.Glowing BLACK = new ItemSprite.Glowing( 0x000000 );
@Override
public int proc(Weapon weapon, Char attacker, Char defender, int damage ) {
if (attacker == Dungeon.hero && Random.Int(20) == 0) {
Buff.affect(attacker, Weakness.class, Random.Float(5f, 25f));
}
return damage;
}
@Override
public boolean curse() {
return true;
}
@Override
public ItemSprite.Glowing glowing() {
return BLACK;
}
}

View File

@ -77,8 +77,7 @@ public class MeleeWeapon extends Weapon {
} }
} }
//defense-granting weapons include the DR amount, otherwise the value is discarded. String stats_desc = Messages.get(this, "stats_desc");
String stats_desc = Messages.get(this, "stats_desc", defenceFactor(Dungeon.hero));
if (!stats_desc.equals("")) info+= "\n\n" + stats_desc; if (!stats_desc.equals("")) info+= "\n\n" + stats_desc;
switch (imbue) { switch (imbue) {

View File

@ -53,7 +53,7 @@ public class ArmoryPainter extends Painter {
set( level, statue, Terrain.STATUE ); set( level, statue, Terrain.STATUE );
} }
int n = Random.IntRange( 2, 3 ); int n = Random.IntRange( 1, 2 );
for (int i=0; i < n; i++) { for (int i=0; i < n; i++) {
int pos; int pos;
do { do {

View File

@ -1,6 +1,15 @@
###armor curses ###armor curses
items.armor.curses.antientropy.name=%s of anti-entropy
items.armor.curses.antientropy.desc=Anti-entropy curse works against the forces of the universe, pulling energy away from the attacker and into the wearer. This breifly freezes the attacker, but sets the wearer on fire!
items.armor.curses.displacement.name=%s of displacement
items.armor.curses.displacement.desc=The curse of displacement attempts to move the wearer to safety when they are attacked. It is a bit too effective however, randomly teleporting the user around the level.
items.armor.curses.metabolism.name=%s of metabolism
items.armor.curses.metabolism.desc=The metabolism curse directly converts satiety into health when the wearer is injured, quickly causing starvation.
items.armor.curses.stench.name=%s of stench items.armor.curses.stench.name=%s of stench
items.armor.curses.stench.desc= items.armor.curses.stench.desc=Armor cursed with stench will releaes clouds of noxious gas, which is hazardous to everything caught in the cloud.
@ -8,9 +17,6 @@ items.armor.curses.stench.desc=
items.armor.glyphs.affection.name=%s of affection items.armor.glyphs.affection.name=%s of affection
items.armor.glyphs.affection.desc=This powerful glyph manipulates the mind of attackers, charming them temporarily. items.armor.glyphs.affection.desc=This powerful glyph manipulates the mind of attackers, charming them temporarily.
items.armor.glyphs.antientropy.name=%s of anti-entropy
items.armor.glyphs.antientropy.desc=
items.armor.glyphs.antimagic.name=%s of anti-magic items.armor.glyphs.antimagic.name=%s of anti-magic
items.armor.glyphs.antimagic.desc=This powerful glyph allows armor to apply its defence to most magical attacks as well as phyical ones. items.armor.glyphs.antimagic.desc=This powerful glyph allows armor to apply its defence to most magical attacks as well as phyical ones.
@ -26,9 +32,6 @@ items.armor.glyphs.entanglement.desc=This glyph grows earthroot around the weare
items.armor.glyphs.flow.name=%s of flow 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. items.armor.glyphs.flow.desc=This glyph manipulates the flow of water around the wearer, making them much faster when moving through it.
items.armor.glyphs.metabolism.name=%s of metabolism
items.armor.glyphs.metabolism.desc=
items.armor.glyphs.multiplicity.name=%s of multiplicity items.armor.glyphs.multiplicity.name=%s of multiplicity
items.armor.glyphs.multiplicity.rankings_desc=Killed by: glyph of multiplicity items.armor.glyphs.multiplicity.rankings_desc=Killed by: glyph of multiplicity
items.armor.glyphs.multiplicity.desc= items.armor.glyphs.multiplicity.desc=
@ -696,18 +699,21 @@ items.wands.wandofvenom.desc=This wand has a purple body which opens to a brilli
###weapon curses ###weapon curses
items.weapon.curses.annoying.name=annoying %s items.weapon.curses.annoying.name=annoying %s
items.weapon.curses.annoying.msg_1= items.weapon.curses.annoying.msg_1=OOH, ARE WE FIGHTING SOMETHING!?
items.weapon.curses.annoying.msg_2= items.weapon.curses.annoying.msg_2=YEAH, GET THEM!
items.weapon.curses.annoying.msg_3= items.weapon.curses.annoying.msg_3=HEY, LISTEN!
items.weapon.curses.annoying.msg_4= items.weapon.curses.annoying.msg_4=ARE WE AT THE BOSS YET!?
items.weapon.curses.annoying.msg_5= items.weapon.curses.annoying.msg_5=OUCH, DON'T SWING ME SO HARD!
items.weapon.curses.annoying.desc= items.weapon.curses.annoying.desc=Annoying weapons just want to help. unfortunatley that help comes in the form of a loud voice which attracts enemies.
items.weapon.curses.exhausting.name=exhausting %s
items.weapon.curses.exhausting.desc=Exhausting weapons take great effort to use, and will periodically weaken the wearer as a result.
items.weapon.curses.fragile.name=fragile %s items.weapon.curses.fragile.name=fragile %s
items.weapon.curses.fragile.desc= items.weapon.curses.fragile.desc=Fragile weapons start out just as strong as their uncursed counterparts, but rapidly decrease in effectiveness as they are used.
items.weapon.curses.wayward.name=wayward %s items.weapon.curses.wayward.name=wayward %s
items.weapon.curses.wayward.desc= items.weapon.curses.wayward.desc=A wayward weapon has a very hard time finding its mark, making it extremely inaccurate unless the attack is garunteed to suceed.
###enchantments ###enchantments
@ -781,7 +787,7 @@ items.weapon.melee.greataxe.stats_desc=This weapon is incredibly heavy.
items.weapon.melee.greataxe.desc=Meant to be weilded over the shoulder, this titanic axe is a powerful as it is heavy. items.weapon.melee.greataxe.desc=Meant to be weilded over the shoulder, this titanic axe is a powerful as it is heavy.
items.weapon.melee.greatshield.name=greatshield items.weapon.melee.greatshield.name=greatshield
items.weapon.melee.greatshield.stats_desc=This weapon blocks up to %d damage. items.weapon.melee.greatshield.stats_desc=This weapon blocks a tremendous amount of damage.
items.weapon.melee.greatshield.desc=More like a mobile wall than a shield, this giantic mass of metal aids defence, but doesn't leave much room for attacking. items.weapon.melee.greatshield.desc=More like a mobile wall than a shield, this giantic mass of metal aids defence, but doesn't leave much room for attacking.
items.weapon.melee.greatsword.name=greatsword items.weapon.melee.greatsword.name=greatsword
@ -825,11 +831,11 @@ items.weapon.melee.newshortsword.name=shortsword
items.weapon.melee.newshortsword.desc=A quite short sword, only a few inches longer than a dagger. items.weapon.melee.newshortsword.desc=A quite short sword, only a few inches longer than a dagger.
items.weapon.melee.quarterstaff.name=quarterstaff items.weapon.melee.quarterstaff.name=quarterstaff
items.weapon.melee.quarterstaff.stats_desc=This weapon blocks up to %d damage. items.weapon.melee.quarterstaff.stats_desc=This weapon blocks some damage.
items.weapon.melee.quarterstaff.desc=A staff of hardwood, its ends are shod with iron. items.weapon.melee.quarterstaff.desc=A staff of hardwood, its ends are shod with iron.
items.weapon.melee.roundshield.name=round shield items.weapon.melee.roundshield.name=round shield
items.weapon.melee.roundshield.stats_desc=This weapon blocks up to %d damage. items.weapon.melee.roundshield.stats_desc=This weapon blocks a significant amount of damage.
items.weapon.melee.roundshield.desc=This large shield effectively blocks attacks and makes a decent weapon in a pinch. items.weapon.melee.roundshield.desc=This large shield effectively blocks attacks and makes a decent weapon in a pinch.
items.weapon.melee.runicblade.name=runic blade items.weapon.melee.runicblade.name=runic blade
@ -837,7 +843,7 @@ items.weapon.melee.runicblade.stats_desc=This weapon benefits more from upgrades
items.weapon.melee.runicblade.desc=A mysterious weapon from a distant land, with a bright blue blade. items.weapon.melee.runicblade.desc=A mysterious weapon from a distant land, with a bright blue blade.
items.weapon.melee.sai.name=sai items.weapon.melee.sai.name=sai
items.weapon.melee.sai.stats_desc=This is a very fast weapon.\nThis weapon blocks up to %d damage. items.weapon.melee.sai.stats_desc=This is a very fast weapon.\nThis weapon blocks some damage.
items.weapon.melee.sai.desc=Two thin blades meant to be weilded in one hand each. Excellent for parrying and swift cuts alike. items.weapon.melee.sai.desc=Two thin blades meant to be weilded in one hand each. Excellent for parrying and swift cuts alike.
items.weapon.melee.scimitar.name=scimitar items.weapon.melee.scimitar.name=scimitar