v0.8.1: major buff / rework to ring of wealth

This commit is contained in:
Evan Debenham 2020-06-03 14:46:38 -04:00
parent 128c170301
commit d3d2678ae5
4 changed files with 154 additions and 124 deletions

View File

@ -857,7 +857,7 @@ items.rings.ringoftenacity.desc=When worn, this ring will allow the wearer to re
items.rings.ringofwealth.name=ring of wealth items.rings.ringofwealth.name=ring of wealth
items.rings.ringofwealth.stats=When worn, this ring will increase your luck by _%s%%._ 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.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. items.rings.ringofwealth.desc=This ring acts like a magnet for treasure, increasing the likelihood that enemies and containers will be carrying valuable items. A cursed ring will instead reduce your chance of receiving loot.

View File

@ -674,12 +674,7 @@ public abstract class Mob extends Char {
ArrayList<Item> bonus = RingOfWealth.tryForBonusDrop(Dungeon.hero, rolls); ArrayList<Item> bonus = RingOfWealth.tryForBonusDrop(Dungeon.hero, rolls);
if (bonus != null && !bonus.isEmpty()) { if (bonus != null && !bonus.isEmpty()) {
for (Item b : bonus) Dungeon.level.drop(b, pos).sprite.drop(); for (Item b : bonus) Dungeon.level.drop(b, pos).sprite.drop();
if (RingOfWealth.latestDropWasRare){ RingOfWealth.showFlareForBonusDrop(sprite);
new Flare(8, 48).color(0xAA00FF, true).show(sprite, 3f);
RingOfWealth.latestDropWasRare = false;
} else {
new Flare(8, 24).color(0xFFFFFF, true).show(sprite, 3f);
}
} }
} }

View File

@ -112,12 +112,7 @@ public class Heap implements Bundlable {
ArrayList<Item> bonus = RingOfWealth.tryForBonusDrop(hero, 1); ArrayList<Item> bonus = RingOfWealth.tryForBonusDrop(hero, 1);
if (bonus != null && !bonus.isEmpty()) { if (bonus != null && !bonus.isEmpty()) {
items.addAll(0, bonus); items.addAll(0, bonus);
if (RingOfWealth.latestDropWasRare){ RingOfWealth.showFlareForBonusDrop(sprite);
new Flare(8, 48).color(0xAA00FF, true).show(sprite, 2f);
RingOfWealth.latestDropWasRare = false;
} else {
new Flare(8, 24).color(0xFFFFFF, true).show(sprite, 2f);
}
} }
sprite.link(); sprite.link();
sprite.drop(); sprite.drop();

View File

@ -24,20 +24,27 @@ package com.shatteredpixel.shatteredpixeldungeon.items.rings;
import com.shatteredpixel.shatteredpixeldungeon.Challenges; import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon; import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char; import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.effects.Flare;
import com.shatteredpixel.shatteredpixeldungeon.items.Generator; import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.Gold; import com.shatteredpixel.shatteredpixeldungeon.items.Gold;
import com.shatteredpixel.shatteredpixeldungeon.items.Honeypot;
import com.shatteredpixel.shatteredpixeldungeon.items.Item; import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor; import com.shatteredpixel.shatteredpixeldungeon.items.armor.Armor;
import com.shatteredpixel.shatteredpixeldungeon.items.bombs.Bomb;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.AlchemicalCatalyst; import com.shatteredpixel.shatteredpixeldungeon.items.potions.AlchemicalCatalyst;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfExperience; import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfExperience;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.ExoticPotion;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTransmutation; import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.ScrollOfTransmutation;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.exotic.ExoticScroll;
import com.shatteredpixel.shatteredpixeldungeon.items.spells.ArcaneCatalyst; import com.shatteredpixel.shatteredpixeldungeon.items.spells.ArcaneCatalyst;
import com.shatteredpixel.shatteredpixeldungeon.items.stones.StoneOfEnchantment; import com.shatteredpixel.shatteredpixeldungeon.items.stones.StoneOfEnchantment;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon; import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet; import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.noosa.Visual;
import com.watabou.utils.Bundle; import com.watabou.utils.Bundle;
import com.watabou.utils.Random; import com.watabou.utils.Random;
import com.watabou.utils.Reflection;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
@ -52,13 +59,11 @@ public class RingOfWealth extends Ring {
private float triesToDrop = Float.MIN_VALUE; private float triesToDrop = Float.MIN_VALUE;
private int dropsToRare = Integer.MIN_VALUE; private int dropsToRare = Integer.MIN_VALUE;
public static boolean latestDropWasRare = false;
public String statsInfo() { public String statsInfo() {
if (isIdentified()){ if (isIdentified()){
return Messages.get(this, "stats", new DecimalFormat("#.##").format(100f * (Math.pow(1.2f, soloBuffedBonus()) - 1f))); return Messages.get(this, "stats", new DecimalFormat("#.##").format(100f * (Math.pow(1.25f, soloBuffedBonus()) - 1f)));
} else { } else {
return Messages.get(this, "typical_stats", new DecimalFormat("#.##").format(20f)); return Messages.get(this, "typical_stats", new DecimalFormat("#.##").format(25f));
} }
} }
@ -85,152 +90,151 @@ public class RingOfWealth extends Ring {
} }
public static float dropChanceMultiplier( Char target ){ public static float dropChanceMultiplier( Char target ){
return (float)Math.pow(1.2, getBuffedBonus(target, Wealth.class)); return (float)Math.pow(1.25, getBuffedBonus(target, Wealth.class));
} }
public static ArrayList<Item> tryForBonusDrop(Char target, int tries ){ public static ArrayList<Item> tryForBonusDrop(Char target, int tries ){
if (getBuffedBonus(target, Wealth.class) <= 0) return null; int bonus = getBuffedBonus(target, Wealth.class);
if (bonus <= 0) return null;
HashSet<Wealth> buffs = target.buffs(Wealth.class); HashSet<Wealth> buffs = target.buffs(Wealth.class);
float triesToDrop = Float.MIN_VALUE; float triesToDrop = Float.MIN_VALUE;
int dropsToRare = Integer.MIN_VALUE; int dropsToEquip = Integer.MIN_VALUE;
//find the largest count (if they aren't synced yet) //find the largest count (if they aren't synced yet)
for (Wealth w : buffs){ for (Wealth w : buffs){
if (w.triesToDrop() > triesToDrop){ if (w.triesToDrop() > triesToDrop){
triesToDrop = w.triesToDrop(); triesToDrop = w.triesToDrop();
dropsToRare = w.dropsToRare(); dropsToEquip = w.dropsToRare();
} }
} }
//reset (if needed), decrement, and store counts //reset (if needed), decrement, and store counts
if (triesToDrop == Float.MIN_VALUE) { if (triesToDrop == Float.MIN_VALUE) {
triesToDrop = Random.NormalIntRange(0, 50); triesToDrop = Random.NormalIntRange(0, 30);
dropsToRare = Random.NormalIntRange(5, 10); dropsToEquip = Random.NormalIntRange(5, 10);
} }
//now handle reward logic //now handle reward logic
ArrayList<Item> drops = new ArrayList<>(); ArrayList<Item> drops = new ArrayList<>();
triesToDrop -= dropProgression(target, tries); triesToDrop -= tries;
while ( triesToDrop <= 0 ){ while ( triesToDrop <= 0 ){
if (dropsToRare <= 0){ if (dropsToEquip <= 0){
Item i; Item i;
do { do {
i = genRareDrop(); i = genEquipmentDrop(bonus - 1);
} while (Challenges.isItemBlocked(i)); } while (Challenges.isItemBlocked(i));
drops.add(i); drops.add(i);
latestDropWasRare = true; dropsToEquip = Random.NormalIntRange(5, 10);
dropsToRare = Random.NormalIntRange(5, 10);
} else { } else {
Item i; Item i;
do { do {
i = genStandardDrop(); i = genConsumableDrop(bonus - 1);
} while (Challenges.isItemBlocked(i)); } while (Challenges.isItemBlocked(i));
drops.add(i); drops.add(i);
dropsToRare--; dropsToEquip--;
} }
triesToDrop += Random.NormalIntRange(0, 50); triesToDrop += Random.NormalIntRange(0, 30);
} }
//store values back into rings //store values back into rings
for (Wealth w : buffs){ for (Wealth w : buffs){
w.triesToDrop(triesToDrop); w.triesToDrop(triesToDrop);
w.dropsToRare(dropsToRare); w.dropsToRare(dropsToEquip);
} }
return drops; return drops;
} }
public static Item genStandardDrop(){ //used for visuals
float roll = Random.Float(); // 1/2/3 used for low/mid/high tier consumables
if (roll < 0.3f){ //30% chance // 3 used for +0-1 equips, 4 used for +2 or higher equips
Item result = new Gold().random(); private static int latestDropTier = 0;
result.quantity(Math.round(result.quantity() * Random.NormalFloat(0.33f, 1f)));
return result; public static void showFlareForBonusDrop( Visual vis ){
} else if (roll < 0.7f){ //40% chance switch (latestDropTier){
return genBasicConsumable(); default:
} else if (roll < 0.9f){ //20% chance break; //do nothing
return genExoticConsumable(); case 1:
} else { //10% chance new Flare(6, 20).color(0x00FF00, true).show(vis, 3f);
if (Random.Int(3) != 0){ break;
Weapon weapon = Generator.randomWeapon(); case 2:
weapon.enchant(null); new Flare(6, 24).color(0x00AAFF, true).show(vis, 3.33f);
weapon.cursed = false; break;
weapon.cursedKnown = true; case 3:
weapon.level(0); new Flare(6, 28).color(0xAA00FF, true).show(vis, 3.67f);
return weapon; break;
} else { case 4:
Armor armor = Generator.randomArmor(); new Flare(6, 32).color(0xFFAA00, true).show(vis, 4f);
armor.inscribe(null); break;
armor.cursed = false;
armor.cursedKnown = true;
armor.level(0);
return armor;
}
} }
latestDropTier = 0;
} }
private static Item genBasicConsumable(){ public static Item genConsumableDrop(int level) {
float roll = Random.Float(); float roll = Random.Float();
if (roll < 0.4f){ //40% chance //60% chance - 4% per level. Starting from +15: 0%
return Generator.random(Generator.Category.STONE); if (roll < (0.6f - 0.04f * level)) {
} else if (roll < 0.7f){ //30% chance latestDropTier = 1;
return Generator.random(Generator.Category.POTION); return genLowValueConsumable();
} else { //30% chance //30% chance + 2% per level. Starting from +15: 60%-2%*lvl
return Generator.random(Generator.Category.SCROLL); } else if (roll < (0.9f - 0.02f * level)) {
} latestDropTier = 2;
} return genMidValueConsumable();
//10% chance + 2% per level. Starting from +15: 40%+2%*lvl
private static Item genExoticConsumable(){ } else {
float roll = Random.Float(); latestDropTier = 3;
if (roll < 0.3f){ //30% chance
return Generator.random(Generator.Category.POTION);
} else if (roll < 0.6f) { //30% chance
return Generator.random(Generator.Category.SCROLL);
} else { //40% chance
return Random.Int(2) == 0 ? new AlchemicalCatalyst() : new ArcaneCatalyst();
}
}
public static Item genRareDrop(){
float roll = Random.Float();
if (roll < 0.3f){ //30% chance
Item result = new Gold().random();
result.quantity(Math.round(result.quantity() * Random.NormalFloat(3f, 6f)));
return result;
} else if (roll < 0.7f){ //40% chance
return genHighValueConsumable(); return genHighValueConsumable();
} else if (roll < 0.9f){ //20% chance }
Item result = Random.Int(2) == 0 ? Generator.random(Generator.Category.ARTIFACT) : Generator.random(Generator.Category.RING); }
result.cursed = false;
result.cursedKnown = true; private static Item genLowValueConsumable(){
return result; switch (Random.Int(4)){
} else { //10% chance case 0: default:
if (Random.Int(3) != 0){ Item i = new Gold().random();
Weapon weapon = Generator.randomWeapon((Dungeon.depth / 5) + 1); return i.quantity(i.quantity()/2);
weapon.upgrade(1); case 1:
weapon.enchant(Weapon.Enchantment.random()); return Generator.random(Generator.Category.STONE);
weapon.cursed = false; case 2:
weapon.cursedKnown = true; return Generator.random(Generator.Category.POTION);
return weapon; case 3:
} else { return Generator.random(Generator.Category.SCROLL);
Armor armor = Generator.randomArmor((Dungeon.depth / 5) + 1); }
armor.upgrade(); }
armor.inscribe(Armor.Glyph.random());
armor.cursed = false; private static Item genMidValueConsumable(){
armor.cursedKnown = true; switch (Random.Int(6)){
return armor; case 0: default:
} Item i = genLowValueConsumable();
return i.quantity(i.quantity()*2);
case 1:
i = Generator.randomUsingDefaults(Generator.Category.POTION);
return Reflection.newInstance(ExoticPotion.regToExo.get(i.getClass()));
case 2:
i = Generator.randomUsingDefaults(Generator.Category.SCROLL);
return Reflection.newInstance(ExoticScroll.regToExo.get(i.getClass()));
case 3:
return Random.Int(2) == 0 ? new ArcaneCatalyst() : new AlchemicalCatalyst();
case 4:
return new Bomb();
case 5:
return new Honeypot();
} }
} }
private static Item genHighValueConsumable(){ private static Item genHighValueConsumable(){
switch( Random.Int(4) ){ //25% chance each switch (Random.Int(4)){
case 0: default: case 0: default:
return new StoneOfEnchantment(); Item i = genLowValueConsumable();
if (i instanceof Bomb){
return new Bomb.DoubleBomb();
} else {
return i.quantity(i.quantity() * 2);
}
case 1: case 1:
return new StoneOfEnchantment().quantity(2); return new StoneOfEnchantment();
case 2: case 2:
return new PotionOfExperience(); return new PotionOfExperience();
case 3: case 3:
@ -238,8 +242,44 @@ public class RingOfWealth extends Ring {
} }
} }
private static float dropProgression( Char target, int tries ){ private static Item genEquipmentDrop( int level ){
return tries * (float)Math.pow(1.2f, getBuffedBonus(target, Wealth.class) ); Item result;
//each upgrade increases depth used for calculating drops by 1
int floorset = (Dungeon.depth + level)/5;
switch (Random.Int(5)){
default: case 0: case 1:
Weapon w = Generator.randomWeapon(floorset);
if (!w.hasGoodEnchant() && Random.Int(10-level) == 0) w.enchant();
else if (w.hasCurseEnchant()) w.enchant(null);
result = w;
break;
case 2:
Armor a = Generator.randomArmor(floorset);
if (!a.hasGoodGlyph() && Random.Int(10-level) == 0) a.inscribe();
else if (a.hasCurseGlyph()) a.inscribe(null);
result = a;
break;
case 3:
result = Generator.random(Generator.Category.RING);
break;
case 4:
result = Generator.random(Generator.Category.ARTIFACT);
break;
}
//minimum level of sqrt(ringLvl)
if (result.isUpgradable()){
if (result.level() < Math.floor(Math.sqrt(level))){
result.level((int)Math.floor(Math.sqrt(level)));
}
}
result.cursed = false;
result.cursedKnown = true;
if (result.level() >= 2) {
latestDropTier = 4;
} else {
latestDropTier = 3;
}
return result;
} }
public class Wealth extends RingBuff { public class Wealth extends RingBuff {