v0.7.1: various ring adjustments/improvements:

- rings now display statistical information about their effects
- ring of accuracy now boosts hero accuracy, instead of reducing enemy evasion
- ring of energy buffed, now provides a percentage boost to charge speed
- ring of furor rebalanced, no longger better with slower weapons
This commit is contained in:
Evan Debenham 2018-11-16 01:48:50 -05:00
parent 054c20ef62
commit 72249110bf
17 changed files with 215 additions and 41 deletions

View File

@ -80,6 +80,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.keys.Key;
import com.shatteredpixel.shatteredpixeldungeon.items.keys.SkeletonKey;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfStrength;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfAccuracy;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEvasion;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfForce;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfFuror;
@ -308,6 +309,8 @@ public class Hero extends Char {
KindOfWeapon wep = belongings.weapon;
float accuracy = 1;
accuracy *= RingOfAccuracy.accuracyMultiplier( this );
if (wep instanceof MissileWeapon && rangedAttack
&& Dungeon.level.distance( pos, target.pos ) == 1) {
accuracy *= 0.5f;
@ -437,7 +440,7 @@ public class Hero extends Char {
//Normally putting furor speed on unarmed attacks would be unnecessary
//But there's going to be that one guy who gets a furor+force ring combo
//This is for that one guy, you shall get your fists of fury!
return RingOfFuror.modifyAttackDelay(1f, this);
return RingOfFuror.attackDelayMultiplier(this);
}
}

View File

@ -48,7 +48,6 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.TimekeepersHourglass;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfAccuracy;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfWealth;
import com.shatteredpixel.shatteredpixeldungeon.items.stones.StoneOfAggression;
import com.shatteredpixel.shatteredpixeldungeon.levels.features.Chasm;
@ -498,9 +497,7 @@ public abstract class Mob extends Char {
if ( seen
&& paralysed == 0
&& !(alignment == Alignment.ALLY && enemy == Dungeon.hero)) {
int defenseSkill = this.defenseSkill;
defenseSkill *= RingOfAccuracy.enemyEvasionMultiplier( enemy );
return defenseSkill;
return this.defenseSkill;
} else {
return 0;
}

View File

@ -155,9 +155,9 @@ public class Ring extends KindofMisc {
}
@Override
public String info() {
public String desc() {
String desc = isKnown()? desc() : Messages.get(this, "unknown_desc");
String desc = isKnown() ? super.desc() : Messages.get(this, "unknown_desc");
if (cursed && isEquipped( Dungeon.hero )) {
desc += "\n\n" + Messages.get(Ring.class, "cursed_worn");
@ -281,6 +281,14 @@ public class Ring extends KindofMisc {
return bonus;
}
public int soloBonus(){
if (cursed){
return Math.min( 0, Ring.this.level()-2 );
} else {
return Ring.this.level()+1;
}
}
public class RingBuff extends Buff {
@Override
@ -298,11 +306,7 @@ public class Ring extends KindofMisc {
}
public int level(){
if (Ring.this.cursed){
return Math.min( 0, Ring.this.level()-2 );
} else {
return Ring.this.level()+1;
}
return Ring.this.soloBonus();
}
}

View File

@ -22,18 +22,31 @@
package com.shatteredpixel.shatteredpixeldungeon.items.rings;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import java.text.DecimalFormat;
public class RingOfAccuracy extends Ring {
public String info() {
String desc = desc();
if (isKnown()){
if (isIdentified()){
desc += "\n\n" + Messages.get(this, "stats", new DecimalFormat("#.##").format(100f * (Math.pow(1.3f, soloBonus()) - 1f)));
} else {
desc += "\n\n" + Messages.get(this, "typical_stats", new DecimalFormat("#.##").format(30f));
}
}
return desc;
}
@Override
protected RingBuff buff( ) {
return new Accuracy();
}
//The ring of accuracy reduces enemy evasion
// this makes it more powerful against more evasive enemies
public static float enemyEvasionMultiplier( Char target ){
return (float)Math.pow(0.75, getBonus(target, Accuracy.class));
public static float accuracyMultiplier( Char target ){
return (float)Math.pow(1.3f, getBonus(target, Accuracy.class));
}
public class Accuracy extends RingBuff {

View File

@ -39,11 +39,25 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Warlock;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.Yog;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.DisintegrationTrap;
import com.shatteredpixel.shatteredpixeldungeon.levels.traps.GrimTrap;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import java.text.DecimalFormat;
import java.util.HashSet;
public class RingOfElements extends Ring {
public String info() {
String desc = desc();
if (isKnown()){
if (isIdentified()){
desc += "\n\n" + Messages.get(this, "stats", new DecimalFormat("#.##").format(100f * (1f - Math.pow(0.875f, soloBonus()))));
} else {
desc += "\n\n" + Messages.get(this, "typical_stats", new DecimalFormat("#.##").format(12.5f));
}
}
return desc;
}
@Override
protected RingBuff buff( ) {
return new Resistance();

View File

@ -21,13 +21,34 @@
package com.shatteredpixel.shatteredpixeldungeon.items.rings;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import java.text.DecimalFormat;
public class RingOfEnergy extends Ring {
public String info() {
String desc = desc();
if (isKnown()){
if (isIdentified()){
desc += "\n\n" + Messages.get(this, "stats", new DecimalFormat("#.##").format(100f * (Math.pow(1.2f, soloBonus()) - 1f)));
} else {
desc += "\n\n" + Messages.get(this, "typical_stats", new DecimalFormat("#.##").format(20f));
}
}
return desc;
}
@Override
protected RingBuff buff( ) {
return new Energy();
}
public static float wandChargeMultiplier( Char target ){
return (float)Math.pow(1.2, getBonus(target, Energy.class));
}
public class Energy extends RingBuff {
}
}

View File

@ -22,9 +22,24 @@
package com.shatteredpixel.shatteredpixeldungeon.items.rings;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import java.text.DecimalFormat;
public class RingOfEvasion extends Ring {
public String info() {
String desc = desc();
if (isKnown()){
if (isIdentified()){
desc += "\n\n" + Messages.get(this, "stats", new DecimalFormat("#.##").format(100f * (Math.pow(1.15f, soloBonus()) - 1f)));
} else {
desc += "\n\n" + Messages.get(this, "typical_stats", new DecimalFormat("#.##").format(15f));
}
}
return desc;
}
@Override
protected RingBuff buff( ) {
return new Evasion();

View File

@ -63,30 +63,31 @@ public class RingOfForce extends Ring {
//same as equivalent tier weapon
private static int min(int lvl, float tier){
return Math.round(
return Math.max( 0, Math.round(
tier + //base
lvl //level scaling
);
));
}
//same as equivalent tier weapon
private static int max(int lvl, float tier){
return Math.round(
return Math.max( 0, Math.round(
5*(tier+1) + //base
lvl*(tier+1) //level scaling
);
));
}
@Override
public String desc() {
String desc = super.desc();
float tier = tier(Dungeon.hero.STR());
if (levelKnown) {
desc += "\n\n" + Messages.get(this, "avg_dmg", min(level(), tier), max(level(), tier));
} else {
desc += "\n\n" + Messages.get(this, "typical_avg_dmg", min(1, tier), max(1, tier));
if (isKnown()) {
float tier = tier(Dungeon.hero.STR());
if (isIdentified()) {
desc += "\n\n" + Messages.get(this, "stats", min(soloBonus(), tier), max(soloBonus(), tier));
} else {
desc += "\n\n" + Messages.get(this, "typical_stats", min(1, tier), max(1, tier));
}
}
return desc;
}

View File

@ -22,17 +22,31 @@
package com.shatteredpixel.shatteredpixeldungeon.items.rings;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import java.text.DecimalFormat;
public class RingOfFuror extends Ring {
public String info() {
String desc = desc();
if (isKnown()){
if (isIdentified()){
desc += "\n\n" + Messages.get(this, "stats", new DecimalFormat("#.##").format(100f * (Math.pow(1.125f, soloBonus()) - 1f)));
} else {
desc += "\n\n" + Messages.get(this, "typical_stats", new DecimalFormat("#.##").format(12.5f));
}
}
return desc;
}
@Override
protected RingBuff buff( ) {
return new Furor();
}
public static float modifyAttackDelay( float delay, Char target){
//furor bonus only affects delay after 0.2
return (float)(0.2 + (delay - 0.2)*Math.pow(0.85, getBonus(target, Furor.class)));
public static float attackDelayMultiplier(Char target ){
return 1f / (float)Math.pow(1.125, getBonus(target, Furor.class));
}
public class Furor extends RingBuff {

View File

@ -22,9 +22,24 @@
package com.shatteredpixel.shatteredpixeldungeon.items.rings;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import java.text.DecimalFormat;
public class RingOfHaste extends Ring {
public String info() {
String desc = desc();
if (isKnown()){
if (isIdentified()){
desc += "\n\n" + Messages.get(this, "stats", new DecimalFormat("#.##").format(100f * (Math.pow(1.2f, soloBonus()) - 1f)));
} else {
desc += "\n\n" + Messages.get(this, "typical_stats", new DecimalFormat("#.##").format(20f));
}
}
return desc;
}
@Override
protected RingBuff buff( ) {
return new Haste();

View File

@ -25,6 +25,9 @@ package com.shatteredpixel.shatteredpixeldungeon.items.rings;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import java.text.DecimalFormat;
public class RingOfMight extends Ring {
@ -67,6 +70,18 @@ public class RingOfMight extends Ring {
}
}
public String info() {
String desc = desc();
if (isKnown()){
if (isIdentified()){
desc += "\n\n" + Messages.get(this, "stats", soloBonus(), new DecimalFormat("#.##").format(100f * (Math.pow(1.035, soloBonus()) - 1f)));
} else {
desc += "\n\n" + Messages.get(this, "typical_stats", 1, new DecimalFormat("#.##").format(3.5f));
}
}
return desc;
}
@Override
protected RingBuff buff( ) {
return new Might();

View File

@ -22,9 +22,24 @@
package com.shatteredpixel.shatteredpixeldungeon.items.rings;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import java.text.DecimalFormat;
public class RingOfSharpshooting extends Ring {
public String info() {
String desc = desc();
if (isKnown()){
if (isIdentified()){
desc += "\n\n" + Messages.get(this, "stats", soloBonus(), new DecimalFormat("#.##").format(100f * (Math.pow(1.2, soloBonus()) - 1f)));
} else {
desc += "\n\n" + Messages.get(this, "typical_stats", 1, new DecimalFormat("#.##").format(20f));
}
}
return desc;
}
@Override
protected RingBuff buff( ) {
return new Aim();

View File

@ -22,9 +22,24 @@
package com.shatteredpixel.shatteredpixeldungeon.items.rings;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import java.text.DecimalFormat;
public class RingOfTenacity extends Ring {
public String info() {
String desc = desc();
if (isKnown()){
if (isIdentified()){
desc += "\n\n" + Messages.get(this, "stats", new DecimalFormat("#.##").format(100f * (1f - Math.pow(0.85f, soloBonus()))));
} else {
desc += "\n\n" + Messages.get(this, "typical_stats", new DecimalFormat("#.##").format(15f));
}
}
return desc;
}
@Override
protected RingBuff buff( ) {
return new Tenacity();

View File

@ -27,8 +27,10 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Gold;
import com.shatteredpixel.shatteredpixeldungeon.items.Honeypot;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.bombs.Bomb;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.watabou.utils.Random;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashSet;
@ -36,6 +38,18 @@ public class RingOfWealth extends Ring {
private float triesToDrop = 0;
public String info() {
String desc = desc();
if (isKnown()){
if (isIdentified()){
desc += "\n\n" + Messages.get(this, "stats", new DecimalFormat("#.##").format(100f * (Math.pow(1.15f, soloBonus()) - 1f)));
} else {
desc += "\n\n" + Messages.get(this, "typical_stats", new DecimalFormat("#.##").format(15f));
}
}
return desc;
}
@Override
protected RingBuff buff( ) {
return new Wealth();

View File

@ -38,7 +38,6 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.MagicMissile;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.MagicalHolster;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEnergy;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.melee.MagesStaff;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
@ -453,7 +452,6 @@ public abstract class Wand extends Item {
private void recharge(){
int missingCharges = maxCharges - curCharges;
missingCharges += Ring.getBonus(target, RingOfEnergy.Energy.class);
missingCharges = Math.max(0, missingCharges);
float turnsToCharge = (float) (BASE_CHARGE_DELAY
@ -461,7 +459,7 @@ public abstract class Wand extends Item {
LockedFloor lock = target.buff(LockedFloor.class);
if (lock == null || lock.regenOn())
partialCharge += 1f/turnsToCharge;
partialCharge += (1f/turnsToCharge) * RingOfEnergy.wandChargeMultiplier(target);
for (Recharging bonus : target.buffs(Recharging.class)){
if (bonus != null && bonus.remainder() > 0f) {

View File

@ -171,7 +171,7 @@ abstract public class Weapon extends KindOfWeapon {
float DLY = augment.delayFactor(this.DLY);
DLY = RingOfFuror.modifyAttackDelay(DLY, owner);
DLY *= RingOfFuror.attackDelayMultiplier(owner);
return (encumbrance > 0 ? (float)(DLY * Math.pow( 1.2, encumbrance )) : DLY);
}

View File

@ -729,38 +729,58 @@ items.rings.ring.curse_known=You can feel a malevolent magic lurking within this
items.rings.ring.not_cursed=This ring is free of malevolent magic.
items.rings.ringofaccuracy.name=ring of accuracy
items.rings.ringofaccuracy.desc=This ring increases your focus, reducing your enemy's ability to dodge your attacks. A cursed ring will instead make it easier for enemies to evade your attacks.
items.rings.ringofaccuracy.stats=When worn, this ring will increase your accuracy by _%s%%._
items.rings.ringofaccuracy.typical_stats=When worn, this ring will typically increase your accuracy by _%s%%._
items.rings.ringofaccuracy.desc=This ring increases your focus, making it easier for your attacks to find their mark. A cursed ring will instead make it harder for your attacks to connect.
items.rings.ringofelements.name=ring of elements
items.rings.ringofelements.stats=When worn, this ring will provide _%s%%_ elemental resistance.
items.rings.ringofelements.typical_stats=When worn, this ring will typically provide _%s%%_ elemental resistance.
items.rings.ringofelements.desc=This ring provides resistance to most elemental and magical effects, decreasing damage and debuff duration. Naturally a cursed ring will instead worsen these effects.
items.rings.ringofenergy.name=ring of energy
items.rings.ringofenergy.stats=When worn, this ring will increase wand charge speed by _%s%%._
items.rings.ringofenergy.typical_stats=When worn, this ring will typically increase wand charge speed by _%s%%._
items.rings.ringofenergy.desc=Your wands will recharge more quickly in the arcane field that radiates from this ring. A cursed ring will instead slow wand recharge.
items.rings.ringofevasion.name=ring of evasion
items.rings.ringofevasion.stats=When worn, this ring will increase your evasion by _%s%%._
items.rings.ringofevasion.typical_stats=When worn, this ring will typically increase your evasion by _%s%%._
items.rings.ringofevasion.desc=This ring quickens the wearer's reactions, making it harder to land blows on them. A cursed ring will instead make the user easier to strike.
items.rings.ringofforce.name=ring of force
items.rings.ringofforce.avg_dmg=When unarmed, at your current strength, this ring will deal _%1$d-%2$d damage._
items.rings.ringofforce.typical_avg_dmg=When unarmed, at your current strength, typically this ring will deal _%1$d-%2$d damage._
items.rings.ringofforce.stats=When unarmed, at your current strength, this ring will deal _%1$d-%2$d damage._
items.rings.ringofforce.typical_stats=When unarmed, at your current strength, typically this ring will deal _%1$d-%2$d damage._
items.rings.ringofforce.desc=This ring enhances the force of the wearer's blows. This extra power is fairly weak when wielding weapons, but an unarmed attack will be made much stronger. A cursed ring will instead weaken the wearer's blows.
items.rings.ringoffuror.name=ring of furor
items.rings.ringoffuror.desc=This ring grants the wearer an inner fury, allowing them to attack more rapidly. This fury works best in large bursts, so slow weapons benefit far more than fast ones. A cursed ring will instead slow the wearer's speed of attack.
items.rings.ringoffuror.stats=When worn, this ring will increase the speed of your attacks by _%s%%._
items.rings.ringoffuror.typical_stats=When worn, this ring will typically increase the speed of your attacks by _%s%%._
items.rings.ringoffuror.desc=This ring grants the wearer an inner fury, allowing them to attack more rapidly. A cursed ring will instead slow the wearer's speed of attack.
items.rings.ringofhaste.name=ring of haste
items.rings.ringofhaste.stats=When worn, this ring will increase your movement speed by _%s%%._
items.rings.ringofhaste.typical_stats=When worn, this ring will typically increase your movement speed by _%s%%._
items.rings.ringofhaste.desc=This ring reduces the stress of movement on the wearer, allowing them to run at superhuman speeds. A cursed ring will instead weigh the wearer down.
items.rings.ringofenergy.name=ring of energy
items.rings.ringofenergy.desc=Your wands will recharge more quickly in the arcane field that radiates from this ring. A cursed ring will instead slow wand recharge.
items.rings.ringofmight.name=ring of might
items.rings.ringofmight.stats=When worn, this ring will increase your strength by _%1$d_ and your max HP by _%2$s%%._
items.rings.ringofmight.typical_stats=When worn, this ring will typically increase your strength by _%1$d_ and your max HP by _%2$s%%._
items.rings.ringofmight.desc=This ring enhances the physical traits of the wearer, granting them greater physical strength and constitution. A cursed ring will weaken the wearer.
items.rings.ringofsharpshooting.name=ring of sharpshooting
items.rings.ringofsharpshooting.stats=When worn, this ring will increase the effective level of your thrown weapons by _%1$d_ and will increase their durability by _%2$s%%._
items.rings.ringofsharpshooting.typical_stats=When worn, this ring will typically increase the effective level of your thrown weapons by _%1$d_ and will increase their durability by _%2$s%%._
items.rings.ringofsharpshooting.desc=This ring enhances the wearer's precision and aim, which will make all projectile weapons more damaging and durable. A cursed ring will have the opposite effect.
items.rings.ringoftenacity.name=ring of tenacity
items.rings.ringoftenacity.stats=When worn, this ring will reduce the damage you take by up to _%s%%._
items.rings.ringoftenacity.typical_stats=When worn, this ring will typically reduce the damage you take by up to _%s%%._
items.rings.ringoftenacity.desc=When worn, this ring will allow the wearer to resist normally mortal strikes. The more injured the user is, the more resistant they will be to damage. A cursed ring will instead make it easier for enemies to execute the wearer.
items.rings.ringofwealth.name=ring of wealth
items.rings.ringofwealth.stats=When worn, this ring will increase your luck by _%s%%._
items.rings.ringofwealth.typical_stats=When worn, this ring will typically increase your luck by _%s%%._
items.rings.ringofwealth.desc=It's not clear what this ring does exactly, good luck may influence the life of an adventurer in many subtle ways. Naturally a cursed ring would give bad luck.