v2.0.0: various item balance changes

This commit is contained in:
Evan Debenham
2023-01-26 14:57:17 -05:00
parent e3cf0a7f26
commit 783a8bde1d
17 changed files with 67 additions and 46 deletions

View File

@@ -171,7 +171,7 @@ actors.buffs.degrade.heromsg=Your equipment feels weaker!
actors.buffs.degrade.desc=Powerful dark magic is sapping the strength that scrolls of upgrade have applied to your equipment!\n\nWhile degraded, upgraded gear will be treated as if it is a lower level than it actually is. _Every upgrade after +3 becomes exponentially weaker than the last one._ The descriptions of your items will change to reflect their reduced power level.\n\nDegradation does not affect strength requirements, wand charges, durability of thrown weapons, or artifacts.\n\nTurns of degradation remaining: %s. Using a scroll of upgrade or remove curse will end degradation immediately.
actors.buffs.doom.name=doomed
actors.buffs.doom.desc=It's hard to keep going when it seems like the universe wants you dead.\n\nDoomed characters will receive double damage from all sources.\n\nDoom is permanent, its effects only end in death.
actors.buffs.doom.desc=It's hard to keep going when it seems like the universe wants you dead.\n\nDoomed characters will receive +67% damage from all sources.\n\nDoom is permanent, its effects only end in death.
actors.buffs.dread.name=dread
actors.buffs.dread.desc=A terror so great that it will cause its target to flee the dungeon entirely!\n\nCreatures affected by dread will run from their opponent at high speed, and will disappear from the dungeon entirely once they are out of sight. Enemies that are defeated this way award half experience and drop no items. The shock of pain will lessen the duration of dread.\n\nTurns of dread remaining: %d.

View File

@@ -145,9 +145,9 @@ items.artifacts.alchemiststoolkit.ac_brew=BREW
items.artifacts.alchemiststoolkit.ac_energize=ENERGIZE
items.artifacts.alchemiststoolkit.not_ready=Your toolkit has not finished warming up.
items.artifacts.alchemiststoolkit.cursed=Your cursed toolkit prevents you from using alchemy!
items.artifacts.alchemiststoolkit.need_energy=You need at least 5 energy for that.
items.artifacts.alchemiststoolkit.energize_desc=Every 5 energy crystals will give the toolkit enough energy to gain a level, which increases the rate that the toolkit generates energy over time, and how quickly it warms up.\n\nHow much energy would you like to use?
items.artifacts.alchemiststoolkit.energize_1=5 energy: +1 level
items.artifacts.alchemiststoolkit.need_energy=You need at least 6 energy for that.
items.artifacts.alchemiststoolkit.energize_desc=Every 6 energy crystals will give the toolkit enough energy to gain a level, which increases the rate that the toolkit generates energy over time, and how quickly it warms up.\n\nHow much energy would you like to use?
items.artifacts.alchemiststoolkit.energize_1=6 energy: +1 level
items.artifacts.alchemiststoolkit.energize_all=%1$d energy: +%2$d levels
items.artifacts.alchemiststoolkit.desc=This toolkit contains a number of reagents and herbs along with a small mixing vial, allowing for alchemy on-the-go. The vial contains what looks like alchemical energy crystals in liquid form.
items.artifacts.alchemiststoolkit.desc_cursed=The cursed toolkit has bound itself to your side, and refuses to let you use alchemy.
@@ -888,9 +888,9 @@ items.rings.ringofelements.typical_stats=When worn, this ring will typically pro
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 _%1$s%%_ and artifact charge speed by _%2$s%%._
items.rings.ringofenergy.typical_stats=When worn, this ring will typically increase wand charge speed by _%1$s%%_ and artifact charge speed by _%2$s%%._
items.rings.ringofenergy.desc=Your wands and artifacts will recharge more quickly in the arcane field that radiates from this ring. A cursed ring will instead slow recharge.
items.rings.ringofenergy.stats=When worn, this ring will increase wand, artifact, and heroic armor charge speed by _%s%%._
items.rings.ringofenergy.typical_stats=When worn, this ring will typically increase wand, artifact, and heroic armor charge speed by _%s%%._
items.rings.ringofenergy.desc=Your magical equipment will recharge more quickly in the arcane field that radiates from this ring. A cursed ring will instead slow recharge.
items.rings.ringofevasion.name=ring of evasion
items.rings.ringofevasion.stats=When worn, this ring will increase your evasion by _%s%%._

View File

@@ -657,7 +657,7 @@ public abstract class Char extends Actor {
Buff.detach(this, MagicalSleep.class);
}
if (this.buff(Doom.class) != null && !isImmune(Doom.class)){
dmg *= 2;
dmg *= 1.67f;
}
if (alignment != Alignment.ALLY && this.buff(DeathMark.DeathMarkTracker.class) != null){
dmg *= 1.25f;

View File

@@ -48,7 +48,7 @@ public class Corruption extends AllyBuff {
@Override
public boolean act() {
buildToDamage += target.HT/200f;
buildToDamage += target.HT/100f;
int damage = (int)buildToDamage;
buildToDamage -= damage;

View File

@@ -57,7 +57,8 @@ public class Regeneration extends Buff {
if (regenBuff.isCursed()) {
delay *= 1.5f;
} else {
delay -= regenBuff.itemLevel()*0.9f;
//15% boost at +0, scaling to a 500% boost at +10
delay -= 1.33f + regenBuff.itemLevel()*0.667f;
delay /= RingOfEnergy.artifactChargeMultiplier(target);
}
}

View File

@@ -357,7 +357,7 @@ public class Armor extends EquipableItem {
}
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.25f*buffedLvl()) * glyph.procChanceMultiplier(owner);
speed *= (2f + 0.5f*buffedLvl()) * glyph.procChanceMultiplier(owner);
}
if (hasGlyph(Bulk.class, owner) &&

View File

@@ -33,6 +33,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.hero.abilities.ArmorAbili
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.items.BrokenSeal;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEnergy;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
@@ -304,7 +305,9 @@ abstract public class ClassArmor extends Armor {
public boolean act() {
LockedFloor lock = target.buff(LockedFloor.class);
if (lock == null || lock.regenOn()) {
charge += 100 / 500f; //500 turns to full charge
float chargeGain = 100 / 500f; //500 turns to full charge
chargeGain *= RingOfEnergy.armorChargeMultiplier(target);
charge += chargeGain;
updateQuickslot();
if (charge > 100) {
charge = 100;

View File

@@ -91,10 +91,10 @@ public class AlchemistsToolkit extends Artifact {
} else if (action.equals(AC_ENERGIZE)){
if (!isEquipped(hero)) GLog.i( Messages.get(this, "need_to_equip") );
else if (cursed) GLog.w( Messages.get(this, "cursed") );
else if (Dungeon.energy < 5) GLog.w( Messages.get(this, "need_energy") );
else if (Dungeon.energy < 6) GLog.w( Messages.get(this, "need_energy") );
else {
final int maxLevels = Math.min(levelCap - level(), Dungeon.energy/5);
final int maxLevels = Math.min(levelCap - level(), Dungeon.energy/6);
String[] options;
if (maxLevels > 1){
@@ -112,13 +112,13 @@ public class AlchemistsToolkit extends Artifact {
super.onSelect(index);
if (index == 0){
Dungeon.energy -= 5;
Dungeon.energy -= 6;
Sample.INSTANCE.play(Assets.Sounds.DRINK);
Sample.INSTANCE.playDelayed(Assets.Sounds.PUFF, 0.5f);
Dungeon.hero.sprite.operate(Dungeon.hero.pos);
upgrade();
} else if (index == 1){
Dungeon.energy -= 5*maxLevels;
Dungeon.energy -= 6*maxLevels;
Sample.INSTANCE.play(Assets.Sounds.DRINK);
Sample.INSTANCE.playDelayed(Assets.Sounds.PUFF, 0.5f);
Dungeon.hero.sprite.operate(Dungeon.hero.pos);
@@ -240,7 +240,7 @@ public class AlchemistsToolkit extends Artifact {
public void gainCharge(float levelPortion) {
if (cursed || target.buff(MagicImmune.class) != null) return;
//generates 2 energy every hero level, +0.1 energy per toolkit level
//generates 2 energy every hero level, +1 energy per toolkit level
//to a max of 12 energy per hero level
//This means that energy absorbed into the kit is recovered in 5 hero levels
float chargeGain = (2 + level()) * levelPortion;

View File

@@ -38,6 +38,7 @@ import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndOptions;
import com.watabou.noosa.audio.Sample;
import com.watabou.utils.Bundle;
import com.watabou.utils.Random;
import java.util.ArrayList;
@@ -94,7 +95,7 @@ public class ChaliceOfBlood extends Artifact {
}
private void prick(Hero hero){
int damage = 3*(level()*level());
int damage = 5 + 3*(level()*level());
Earthroot.Armor armor = hero.buff(Earthroot.Armor.class);
if (armor != null) {
@@ -158,10 +159,16 @@ public class ChaliceOfBlood extends Artifact {
//grants 5 turns of healing up-front, if hero isn't starving
if (target.isStarving()) return;
float healDelay = 10f - level()*0.9f;
float healDelay = 10f - (1.33f + level()*0.667f);
healDelay /= amount;
//effectively 1HP at lvl 0-5, 2HP lvl 6-8, 3HP lvl 9, and 5HP lvl 10.
target.HP = Math.min( target.HT, target.HP + (int)Math.ceil(5/healDelay));
float heal = 5f/healDelay;
//effectively 0.5/1/1.5/2/2.5 HP per turn at +0/+6/+8/+9/+10
if (Random.Float() < heal%1){
heal++;
}
if (heal >= 1f) {
target.HP = Math.min(target.HT, target.HP + (int)heal);
}
}
@Override

View File

@@ -338,7 +338,7 @@ public class EtherealChains extends Artifact {
if (charge > 5+(level()*2)){
levelPortion *= (5+((float)level()*2))/charge;
}
partialCharge += levelPortion*10f;
partialCharge += levelPortion*6f;
if (exp > 100+level()*100 && level() < levelCap){
exp -= 100+level()*100;

View File

@@ -37,6 +37,8 @@ import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.bags.Bag;
import com.shatteredpixel.shatteredpixeldungeon.items.food.Blandfruit;
import com.shatteredpixel.shatteredpixeldungeon.items.food.Food;
import com.shatteredpixel.shatteredpixeldungeon.items.food.MeatPie;
import com.shatteredpixel.shatteredpixeldungeon.items.food.Pasty;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfEnergy;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
@@ -215,6 +217,12 @@ public class HornOfPlenty extends Artifact {
if (level() >= 10) return;
storedFoodEnergy += food.energy;
//Pasties are worth two upgrades instead of 1.5, meat pies are worth 4 instead of 3!
if (food instanceof Pasty){
storedFoodEnergy += Hunger.HUNGRY/2;
} else if (food instanceof MeatPie){
storedFoodEnergy += Hunger.HUNGRY;
}
if (storedFoodEnergy >= Hunger.HUNGRY){
int upgrades = storedFoodEnergy / (int)Hunger.HUNGRY;
upgrades = Math.min(upgrades, 10 - level());

View File

@@ -35,9 +35,9 @@ public class RingOfArcana extends Ring {
public String statsInfo() {
if (isIdentified()){
return Messages.get(this, "stats", new DecimalFormat("#.##").format(100f * (Math.pow(1.15f, soloBuffedBonus()) - 1f)));
return Messages.get(this, "stats", new DecimalFormat("#.##").format(100f * (Math.pow(1.175f, soloBuffedBonus()) - 1f)));
} else {
return Messages.get(this, "typical_stats", new DecimalFormat("#.##").format(15f));
return Messages.get(this, "typical_stats", new DecimalFormat("#.##").format(175f));
}
}
@@ -47,7 +47,7 @@ public class RingOfArcana extends Ring {
}
public static float enchantPowerMultiplier(Char target ){
return (float)Math.pow(1.15f, getBuffedBonus(target, Arcana.class));
return (float)Math.pow(1.175f, getBuffedBonus(target, Arcana.class));
}
public class Arcana extends RingBuff {

View File

@@ -39,11 +39,9 @@ public class RingOfEnergy extends Ring {
public String statsInfo() {
if (isIdentified()){
return Messages.get(this, "stats",
new DecimalFormat("#.##").format(100f * (Math.pow(1.20f, soloBuffedBonus()) - 1f)),
new DecimalFormat("#.##").format(100f * (Math.pow(1.15f, soloBuffedBonus()) - 1f)));
} else {
return Messages.get(this, "typical_stats",
new DecimalFormat("#.##").format(20f),
new DecimalFormat("#.##").format(15f));
}
}
@@ -54,7 +52,7 @@ public class RingOfEnergy extends Ring {
}
public static float wandChargeMultiplier( Char target ){
return (float)Math.pow(1.20, getBuffedBonus(target, Energy.class));
return (float)Math.pow(1.15, getBuffedBonus(target, Energy.class));
}
public static float artifactChargeMultiplier( Char target ){
@@ -66,6 +64,10 @@ public class RingOfEnergy extends Ring {
return bonus;
}
public static float armorChargeMultiplier( Char target ){
return (float)Math.pow(1.15, getBuffedBonus(target, Energy.class));
}
public class Energy extends RingBuff {
}

View File

@@ -137,7 +137,7 @@ public class WandOfCorruption extends Wand {
Statistics.qualifiedForBossChallengeBadge = false;
}
float corruptingPower = 3 + buffedLvl()/2f;
float corruptingPower = 3 + buffedLvl()/3f;
//base enemy resistance is usually based on their exp, but in special cases it is based on other criteria
float enemyResist;
@@ -147,7 +147,7 @@ public class WandOfCorruption extends Wand {
enemyResist = 1 + Dungeon.depth/2f;
} else if (ch instanceof Wraith) {
//divide by 5 as wraiths are always at full HP and are therefore ~5x harder to corrupt
enemyResist = (1f + Dungeon.scalingDepth()/3f) / 5f;
enemyResist = (1f + Dungeon.scalingDepth()/4f) / 5f;
} else if (ch instanceof Swarm){
//child swarms don't give exp, so we force this here.
enemyResist = 1 + AscensionChallenge.AscensionExp(enemy);
@@ -237,10 +237,10 @@ public class WandOfCorruption extends Wand {
public void onHit(MagesStaff staff, Char attacker, Char defender, int damage) {
int level = Math.max( 0, buffedLvl() );
// lvl 0 - 25%
// lvl 1 - 40%
// lvl 2 - 50%
float procChance = (level+1f)/(level+4f) * procChanceMultiplier(attacker);
// lvl 0 - 16%
// lvl 1 - 28.5%
// lvl 2 - 37.5%
float procChance = (level+1f)/(level+6f) * procChanceMultiplier(attacker);
if (Random.Float() < procChance) {
float powerMulti = Math.max(1f, procChance);

View File

@@ -212,10 +212,11 @@ public class WandOfRegrowth extends Wand {
if (level() >= 10){
return Integer.MAX_VALUE;
} else {
//8 charges at base, plus:
//2/3.33/5/7/10/14/20/30/50/110/infinite charges per hero level, based on wand level
//20 charges at base, plus:
//2/3.1/4.2/5.5/6.8/8.4/10.4/13.2/18.0/30.8/inf. charges per hero level, at wand level:
//0/1 /2 /3 /4 /5 /6 /7 /8 /9 /10
float lvl = level();
return Math.round(8 + heroLvl * (2+lvl) * (1f + (lvl/(10 - lvl))));
return Math.round(20 + heroLvl * (2+lvl) * (1f + (lvl/(50 - 5*lvl))));
}
}

View File

@@ -36,18 +36,18 @@ public class Greatshield extends MeleeWeapon {
@Override
public int max(int lvl) {
return Math.round(2.5f*(tier+1)) + //15 base, down from 30
lvl*(tier-2); //+3 per level, down from +6
return Math.round(3f*(tier+1)) + //18 base, down from 20
lvl*(tier-1); //+3 per level, down from +6
}
@Override
public int defenseFactor( Char owner ) {
return 6+3*buffedLvl(); //6 extra defence, plus 3 per level;
return 6+2*buffedLvl(); //6 extra defence, plus 2 per level
}
public String statsInfo(){
if (isIdentified()){
return Messages.get(this, "stats_desc", 6+3*buffedLvl());
return Messages.get(this, "stats_desc", 6+2*buffedLvl());
} else {
return Messages.get(this, "typical_stats_desc", 6);
}

View File

@@ -43,19 +43,18 @@ public class RoundShield extends MeleeWeapon {
@Override
public int max(int lvl) {
return Math.round(2.5f*(tier+1)) + //10 base, down from 20
lvl*(tier-1); //+2 per level, down from +4
return Math.round(3f*(tier+1)) + //12 base, down from 20
lvl*(tier-1); //+2 per level, down from +4
}
@Override
public int defenseFactor( Char owner ) {
return 4+2*buffedLvl(); //4 extra defence, plus 2 per level;
return 4+buffedLvl(); //4 extra defence, plus 1 per level
}
public String statsInfo(){
if (isIdentified()){
return Messages.get(this, "stats_desc", 4+2*buffedLvl());
return Messages.get(this, "stats_desc", 4+buffedLvl());
} else {
return Messages.get(this, "typical_stats_desc", 4);
}