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.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.
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);
if (bonus != null && !bonus.isEmpty()) {
for (Item b : bonus) Dungeon.level.drop(b, pos).sprite.drop();
if (RingOfWealth.latestDropWasRare){
new Flare(8, 48).color(0xAA00FF, true).show(sprite, 3f);
RingOfWealth.latestDropWasRare = false;
} else {
new Flare(8, 24).color(0xFFFFFF, true).show(sprite, 3f);
}
RingOfWealth.showFlareForBonusDrop(sprite);
}
}

View File

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

View File

@ -24,20 +24,27 @@ package com.shatteredpixel.shatteredpixeldungeon.items.rings;
import com.shatteredpixel.shatteredpixeldungeon.Challenges;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.effects.Flare;
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.Gold;
import com.shatteredpixel.shatteredpixeldungeon.items.Honeypot;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
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.PotionOfExperience;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.exotic.ExoticPotion;
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.stones.StoneOfEnchantment;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.Weapon;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSpriteSheet;
import com.watabou.noosa.Visual;
import com.watabou.utils.Bundle;
import com.watabou.utils.Random;
import com.watabou.utils.Reflection;
import java.text.DecimalFormat;
import java.util.ArrayList;
@ -51,14 +58,12 @@ public class RingOfWealth extends Ring {
private float triesToDrop = Float.MIN_VALUE;
private int dropsToRare = Integer.MIN_VALUE;
public static boolean latestDropWasRare = false;
public String statsInfo() {
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 {
return Messages.get(this, "typical_stats", new DecimalFormat("#.##").format(20f));
return Messages.get(this, "typical_stats", new DecimalFormat("#.##").format(25f));
}
}
@ -85,161 +90,196 @@ public class RingOfWealth extends Ring {
}
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 ){
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);
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)
for (Wealth w : buffs){
if (w.triesToDrop() > triesToDrop){
triesToDrop = w.triesToDrop();
dropsToRare = w.dropsToRare();
dropsToEquip = w.dropsToRare();
}
}
//reset (if needed), decrement, and store counts
if (triesToDrop == Float.MIN_VALUE) {
triesToDrop = Random.NormalIntRange(0, 50);
dropsToRare = Random.NormalIntRange(5, 10);
triesToDrop = Random.NormalIntRange(0, 30);
dropsToEquip = Random.NormalIntRange(5, 10);
}
//now handle reward logic
ArrayList<Item> drops = new ArrayList<>();
triesToDrop -= dropProgression(target, tries);
triesToDrop -= tries;
while ( triesToDrop <= 0 ){
if (dropsToRare <= 0){
if (dropsToEquip <= 0){
Item i;
do {
i = genRareDrop();
i = genEquipmentDrop(bonus - 1);
} while (Challenges.isItemBlocked(i));
drops.add(i);
latestDropWasRare = true;
dropsToRare = Random.NormalIntRange(5, 10);
dropsToEquip = Random.NormalIntRange(5, 10);
} else {
Item i;
do {
i = genStandardDrop();
i = genConsumableDrop(bonus - 1);
} while (Challenges.isItemBlocked(i));
drops.add(i);
dropsToRare--;
dropsToEquip--;
}
triesToDrop += Random.NormalIntRange(0, 50);
triesToDrop += Random.NormalIntRange(0, 30);
}
//store values back into rings
for (Wealth w : buffs){
w.triesToDrop(triesToDrop);
w.dropsToRare(dropsToRare);
w.dropsToRare(dropsToEquip);
}
return drops;
}
public static Item genStandardDrop(){
float roll = Random.Float();
if (roll < 0.3f){ //30% chance
Item result = new Gold().random();
result.quantity(Math.round(result.quantity() * Random.NormalFloat(0.33f, 1f)));
return result;
} else if (roll < 0.7f){ //40% chance
return genBasicConsumable();
} else if (roll < 0.9f){ //20% chance
return genExoticConsumable();
} else { //10% chance
if (Random.Int(3) != 0){
Weapon weapon = Generator.randomWeapon();
weapon.enchant(null);
weapon.cursed = false;
weapon.cursedKnown = true;
weapon.level(0);
return weapon;
} else {
Armor armor = Generator.randomArmor();
armor.inscribe(null);
armor.cursed = false;
armor.cursedKnown = true;
armor.level(0);
return armor;
}
}
}
private static Item genBasicConsumable(){
float roll = Random.Float();
if (roll < 0.4f){ //40% chance
return Generator.random(Generator.Category.STONE);
} else if (roll < 0.7f){ //30% chance
return Generator.random(Generator.Category.POTION);
} else { //30% chance
return Generator.random(Generator.Category.SCROLL);
}
}
private static Item genExoticConsumable(){
float roll = Random.Float();
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();
} 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;
return result;
} else { //10% chance
if (Random.Int(3) != 0){
Weapon weapon = Generator.randomWeapon((Dungeon.depth / 5) + 1);
weapon.upgrade(1);
weapon.enchant(Weapon.Enchantment.random());
weapon.cursed = false;
weapon.cursedKnown = true;
return weapon;
} else {
Armor armor = Generator.randomArmor((Dungeon.depth / 5) + 1);
armor.upgrade();
armor.inscribe(Armor.Glyph.random());
armor.cursed = false;
armor.cursedKnown = true;
return armor;
}
}
}
private static Item genHighValueConsumable(){
switch( Random.Int(4) ){ //25% chance each
case 0: default:
return new StoneOfEnchantment();
//used for visuals
// 1/2/3 used for low/mid/high tier consumables
// 3 used for +0-1 equips, 4 used for +2 or higher equips
private static int latestDropTier = 0;
public static void showFlareForBonusDrop( Visual vis ){
switch (latestDropTier){
default:
break; //do nothing
case 1:
return new StoneOfEnchantment().quantity(2);
new Flare(6, 20).color(0x00FF00, true).show(vis, 3f);
break;
case 2:
new Flare(6, 24).color(0x00AAFF, true).show(vis, 3.33f);
break;
case 3:
new Flare(6, 28).color(0xAA00FF, true).show(vis, 3.67f);
break;
case 4:
new Flare(6, 32).color(0xFFAA00, true).show(vis, 4f);
break;
}
latestDropTier = 0;
}
public static Item genConsumableDrop(int level) {
float roll = Random.Float();
//60% chance - 4% per level. Starting from +15: 0%
if (roll < (0.6f - 0.04f * level)) {
latestDropTier = 1;
return genLowValueConsumable();
//30% chance + 2% per level. Starting from +15: 60%-2%*lvl
} else if (roll < (0.9f - 0.02f * level)) {
latestDropTier = 2;
return genMidValueConsumable();
//10% chance + 2% per level. Starting from +15: 40%+2%*lvl
} else {
latestDropTier = 3;
return genHighValueConsumable();
}
}
private static Item genLowValueConsumable(){
switch (Random.Int(4)){
case 0: default:
Item i = new Gold().random();
return i.quantity(i.quantity()/2);
case 1:
return Generator.random(Generator.Category.STONE);
case 2:
return Generator.random(Generator.Category.POTION);
case 3:
return Generator.random(Generator.Category.SCROLL);
}
}
private static Item genMidValueConsumable(){
switch (Random.Int(6)){
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(){
switch (Random.Int(4)){
case 0: default:
Item i = genLowValueConsumable();
if (i instanceof Bomb){
return new Bomb.DoubleBomb();
} else {
return i.quantity(i.quantity() * 2);
}
case 1:
return new StoneOfEnchantment();
case 2:
return new PotionOfExperience();
case 3:
return new ScrollOfTransmutation();
}
}
private static float dropProgression( Char target, int tries ){
return tries * (float)Math.pow(1.2f, getBuffedBonus(target, Wealth.class) );
private static Item genEquipmentDrop( int level ){
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 {