v0.2.3: refactored item dropping, added to/refactored drop limiter variables. Health potions are no longer farmable. This needs testing!

This commit is contained in:
Evan Debenham 2014-12-01 03:28:10 -05:00
parent dd29262806
commit 657d6a68c7
12 changed files with 215 additions and 103 deletions

View File

@ -17,36 +17,28 @@
*/
package com.shatteredpixel.shatteredpixeldungeon;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Blob;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.ConfusionGas;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.Fire;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.ParalyticGas;
import com.shatteredpixel.shatteredpixeldungeon.actors.blobs.ToxicGas;
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLevitation;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLiquidFlame;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfParalyticGas;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfToxicGas;
import com.watabou.noosa.Game;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Amok;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Light;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Blacksmith;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Imp;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Ghost;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Imp;
import com.shatteredpixel.shatteredpixeldungeon.actors.mobs.npcs.Wandmaker;
import com.shatteredpixel.shatteredpixeldungeon.items.Ankh;
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.Potion;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLevitation;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfLiquidFlame;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfParalyticGas;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfToxicGas;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.Ring;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
import com.shatteredpixel.shatteredpixeldungeon.items.wands.Wand;
@ -70,10 +62,18 @@ import com.shatteredpixel.shatteredpixeldungeon.scenes.StartScene;
import com.shatteredpixel.shatteredpixeldungeon.utils.BArray;
import com.shatteredpixel.shatteredpixeldungeon.utils.Utils;
import com.shatteredpixel.shatteredpixeldungeon.windows.WndResurrect;
import com.watabou.noosa.Game;
import com.watabou.utils.Bundle;
import com.watabou.utils.PathFinder;
import com.watabou.utils.Random;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
public class Dungeon {
private static final String NO_TIPS = "The text is indecipherable...";
@ -129,12 +129,28 @@ public class Dungeon {
private static final String TXT_DEAD_END =
"What are you doing here?!";
public static int potionOfStrength;
public static int scrollsOfUpgrade;
public static int arcaneStyli;
public static boolean dewVial; // true if the dew vial can be spawned
public static int transmutation; // depth number for a well of transmutation
//enum of items which have limited spawns, records how many have spawned
//could all be their own separate ints, but this allows iterating, much nicer for bundling/initializing.
public static enum limitedDrops{
strengthPotions,
upgradeScrolls,
arcaneStyli,
//all unlimited health potion sources
swarmHP,
batHP,
warlockHP,
scorpioHP,
cookingHP,
blandfruitSeed;
public int count = 0;
}
public static int challenges;
public static Hero hero;
@ -178,9 +194,9 @@ public class Dungeon {
depth = 0;
gold = 0;
potionOfStrength = 0;
scrollsOfUpgrade = 0;
arcaneStyli = 0;
for (limitedDrops a : limitedDrops.values())
a.count = 0;
dewVial = true;
transmutation = Random.IntRange( 6, 14 );
@ -374,12 +390,12 @@ public class Dungeon {
public static boolean posNeeded() {
int[] quota = {4, 2, 9, 4, 14, 6, 19, 8, 24, 9};
return chance( quota, potionOfStrength );
return chance( quota, limitedDrops.strengthPotions.count );
}
public static boolean soeNeeded() {
int[] quota = {5, 3, 10, 6, 15, 9, 20, 12, 25, 13};
return chance( quota, scrollsOfUpgrade );
return chance( quota, limitedDrops.upgradeScrolls.count );
}
private static boolean chance( int[] quota, int number ) {
@ -396,7 +412,7 @@ public class Dungeon {
}
public static boolean asNeeded() {
return Random.Int( 12 * (1 + arcaneStyli) ) < depth;
return Random.Int( 12 * (1 + limitedDrops.arcaneStyli.count) ) < depth;
}
private static final String RG_GAME_FILE = "game.dat";
@ -418,15 +434,18 @@ public class Dungeon {
private static final String DEPTH = "depth";
private static final String QUICKSLOT = "quickslot";
private static final String LEVEL = "level";
private static final String POS = "potionsOfStrength";
private static final String SOU = "scrollsOfEnhancement";
private static final String AS = "arcaneStyli";
private static final String LIMDROPS = "limiteddrops";
private static final String DV = "dewVial";
private static final String WT = "transmutation";
private static final String CHAPTERS = "chapters";
private static final String QUESTS = "quests";
private static final String BADGES = "badges";
//TODO: to support pre-0.2.3 saves, remove when needed
private static final String POS = "potionsOfStrength";
private static final String SOU = "scrollsOfEnhancement";
private static final String AS = "arcaneStyli";
public static String gameFile( HeroClass cl ) {
switch (cl) {
case WARRIOR:
@ -463,12 +482,14 @@ public class Dungeon {
bundle.put( GOLD, gold );
bundle.put( DEPTH, depth );
bundle.put( POS, potionOfStrength );
bundle.put( SOU, scrollsOfUpgrade );
bundle.put( AS, arcaneStyli );
bundle.put( DV, dewVial );
bundle.put( WT, transmutation );
int[] dropValues = new int[limitedDrops.values().length];
for (limitedDrops value : limitedDrops.values())
dropValues[value.ordinal()] = value.count;
bundle.put ( LIMDROPS, dropValues );
int count = 0;
int ids[] = new int[chapters.size()];
for (Integer id : chapters) {
@ -567,13 +588,25 @@ public class Dungeon {
Wand.restore( bundle );
Ring.restore( bundle );
potionOfStrength = bundle.getInt( POS );
scrollsOfUpgrade = bundle.getInt( SOU );
arcaneStyli = bundle.getInt( AS );
if (fullLoad) {
dewVial = bundle.getBoolean( DV );
transmutation = bundle.getInt( WT );
if (fullLoad) {
//TODO: adjust this when dropping support for pre-0.2.3 saves
if (bundle.contains( LIMDROPS )) {
int[] dropValues = bundle.getIntArray(LIMDROPS);
for (limitedDrops value : limitedDrops.values())
value.count = value.ordinal() < dropValues.length ?
dropValues[value.ordinal()] : 0;
} else {
for (limitedDrops value : limitedDrops.values())
value.count = 0;
limitedDrops.strengthPotions.count = bundle.getInt(POS);
limitedDrops.upgradeScrolls.count = bundle.getInt(SOU);
limitedDrops.arcaneStyli.count = bundle.getInt(AS);
}
chapters = new HashSet<Integer>();
int ids[] = bundle.getIntArray( CHAPTERS );
if (ids != null) {

View File

@ -19,8 +19,10 @@ package com.shatteredpixel.shatteredpixeldungeon.actors.mobs;
import java.util.HashSet;
import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.effects.Speck;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Leech;
import com.shatteredpixel.shatteredpixeldungeon.sprites.BatSprite;
@ -42,7 +44,7 @@ public class Bat extends Mob {
flying = true;
loot = new PotionOfHealing();
lootChance = 0.125f;
lootChance = 0.1667f; //by default, see die()
}
@Override
@ -78,6 +80,19 @@ public class Bat extends Mob {
return damage;
}
@Override
public void die( Object cause ){
//sets drop chance
lootChance = 1f/((6 + Dungeon.limitedDrops.batHP.count ));
super.die( cause );
}
@Override
protected Item createLoot(){
Dungeon.limitedDrops.batHP.count++;
return super.createLoot();
}
@Override
public String description() {
return

View File

@ -361,8 +361,18 @@ public abstract class Mob extends Char {
super.die( cause );
if (Dungeon.hero.lvl <= maxLvl + 2) {
dropLoot();
float lootChance = this.lootChance;
int bonus = 0;
for (Buff buff : Dungeon.hero.buffs(RingOfWealth.Wealth.class)) {
bonus += ((RingOfWealth.Wealth) buff).level;
}
lootChance *= Math.pow(1.1, bonus);
if (Random.Float() < lootChance && Dungeon.hero.lvl <= maxLvl + 2) {
Item loot = createLoot();
if (loot != null)
Dungeon.level.drop( loot , pos ).sprite.drop();
}
if (Dungeon.hero.isAlive() && !Dungeon.visible[pos]) {
@ -374,17 +384,8 @@ public abstract class Mob extends Char {
protected float lootChance = 0;
@SuppressWarnings("unchecked")
protected void dropLoot() {
float lootChance = this.lootChance;
int bonus = 0;
for (Buff buff : Dungeon.hero.buffs(RingOfWealth.Wealth.class)) {
bonus += ((RingOfWealth.Wealth) buff).level;
}
lootChance *= Math.pow(1.1, bonus);
if (loot != null && Random.Float() < lootChance) {
Item item = null;
protected Item createLoot() {
Item item;
if (loot instanceof Generator.Category) {
item = Generator.random( (Generator.Category)loot );
@ -398,8 +399,7 @@ public abstract class Mob extends Char {
item = (Item)loot;
}
Dungeon.level.drop( item, pos ).sprite.drop();
}
return item;
}
public boolean reset() {

View File

@ -25,6 +25,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Cripple;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Light;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Poison;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.food.MysteryMeat;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Leech;
@ -47,7 +48,7 @@ public class Scorpio extends Mob {
maxLvl = 25;
loot = new PotionOfHealing();
lootChance = 0.125f;
lootChance = 0.2f;
}
@Override
@ -89,11 +90,13 @@ public class Scorpio extends Mob {
}
@Override
protected void dropLoot() {
if (Random.Int( 8 ) == 0) {
Dungeon.level.drop( new PotionOfHealing(), pos ).sprite.drop();
} else if (Random.Int( 6 ) == 0) {
Dungeon.level.drop( new MysteryMeat(), pos ).sprite.drop();
protected Item createLoot() {
//5/count+5 total chance of getting healing, failing the 2nd roll drops mystery meat instead.
if (Random.Int( 5 + Dungeon.limitedDrops.scorpioHP.count ) <= 4) {
Dungeon.limitedDrops.scorpioHP.count++;
return (Item)loot;
} else {
return new MysteryMeat();
}
}

View File

@ -46,6 +46,9 @@ public class Skeleton extends Mob {
EXP = 5;
maxLvl = 10;
loot = Generator.Category.WEAPON;
lootChance = 0.2f;
}
@Override
@ -81,8 +84,7 @@ public class Skeleton extends Mob {
}
@Override
protected void dropLoot() {
if (Random.Int( 5 ) == 0) {
protected Item createLoot() {
Item loot = Generator.random( Generator.Category.WEAPON );
for (int i=0; i < 2; i++) {
Item l = Generator.random( Generator.Category.WEAPON );
@ -90,8 +92,7 @@ public class Skeleton extends Mob {
loot = l;
}
}
Dungeon.level.drop( loot, pos ).sprite.drop();
}
return loot;
}
@Override

View File

@ -26,6 +26,7 @@ import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Burning;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Poison;
import com.shatteredpixel.shatteredpixeldungeon.effects.Pushing;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
@ -47,6 +48,9 @@ public class Swarm extends Mob {
maxLvl = 10;
flying = true;
loot = new PotionOfHealing();
lootChance = 0.2f; //by default, see die()
}
private static final float SPLIT_DELAY = 1f;
@ -130,10 +134,16 @@ public class Swarm extends Mob {
}
@Override
protected void dropLoot() {
if (Random.Int( 6 * (int)Math.pow(2 , generation) ) == 0) {
Dungeon.level.drop( new PotionOfHealing(), pos ).sprite.drop();
public void die( Object cause ){
//sets drop chance
lootChance = 1f/((5 + Dungeon.limitedDrops.swarmHP.count ) * generation );
super.die( cause );
}
@Override
protected Item createLoot(){
Dungeon.limitedDrops.swarmHP.count++;
return super.createLoot();
}
@Override

View File

@ -25,6 +25,8 @@ 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.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.Death;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.mechanics.Ballistica;
@ -125,6 +127,23 @@ public class Warlock extends Mob implements Callback {
next();
}
@Override
public Item createLoot(){
Item loot = super.createLoot();
if (loot instanceof PotionOfHealing){
//count/10 chance of not dropping potion
if (Random.Int(10)-Dungeon.limitedDrops.warlockHP.count < 0){
return null;
} else
Dungeon.limitedDrops.warlockHP.count++;
}
return loot;
}
@Override
public String description() {
return

View File

@ -253,7 +253,7 @@ public class Generator {
}
public static Armor randomArmor(){
int curStr = Hero.STARTING_STR + Dungeon.potionOfStrength;
int curStr = Hero.STARTING_STR + Dungeon.limitedDrops.strengthPotions.count;
return randomArmor(curStr);
}
@ -276,7 +276,7 @@ public class Generator {
}
public static Weapon randomWeapon(){
int curStr = Hero.STARTING_STR + Dungeon.potionOfStrength;
int curStr = Hero.STARTING_STR + Dungeon.limitedDrops.strengthPotions.count;
return randomWeapon(curStr);
}

View File

@ -36,6 +36,7 @@ import com.shatteredpixel.shatteredpixeldungeon.items.food.ChargrilledMeat;
import com.shatteredpixel.shatteredpixeldungeon.items.food.FrozenCarpaccio;
import com.shatteredpixel.shatteredpixeldungeon.items.food.MysteryMeat;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfExperience;
import com.shatteredpixel.shatteredpixeldungeon.items.potions.PotionOfHealing;
import com.shatteredpixel.shatteredpixeldungeon.items.scrolls.Scroll;
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant.Seed;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
@ -283,7 +284,7 @@ public class Heap implements Bundlable {
int bonus = 0;
if (alchemy != null){
bonus = alchemy.level();
if (Random.int(25) < 10+bonus){
if (Random.Int(25) < 10+bonus){
seeds_to_potion--;
if (Random.Int(30) < bonus){
seeds_to_potion--;
@ -296,10 +297,12 @@ public class Heap implements Bundlable {
CellEmitter.get( pos ).burst( Speck.factory( Speck.WOOL ), 6 );
Sample.INSTANCE.play( Assets.SND_PUFF );
Item potion;
//not a buff per-se, meant to cancel out higher potion accuracy when ppl are farming for potions of exp.
if (bonus != 0)
if (Random.Int(1000/bonus) == 0)
return new PotionOfExperience();
potion = new PotionOfExperience();
if (Random.Int( count + bonus ) == 0) {
@ -310,7 +313,7 @@ public class Heap implements Bundlable {
Statistics.potionsCooked++;
Badges.validatePotionsCooked();
return Generator.random( Generator.Category.POTION );
potion = Generator.random( Generator.Category.POTION );
} else {
@ -323,16 +326,24 @@ public class Heap implements Bundlable {
Badges.validatePotionsCooked();
if (itemClass == null) {
return Generator.random( Generator.Category.POTION );
potion = Generator.random( Generator.Category.POTION );
} else {
try {
return itemClass.newInstance();
potion = itemClass.newInstance();
} catch (Exception e) {
return null;
}
}
}
while (potion instanceof PotionOfHealing && Random.Int(15) - Dungeon.limitedDrops.cookingHP.count >= 0)
potion = Generator.random( Generator.Category.POTION );
if (potion instanceof PotionOfHealing)
Dungeon.limitedDrops.cookingHP.count++;
return potion;
} else {
return null;
}

View File

@ -190,15 +190,15 @@ public abstract class Level implements Bundlable {
addItemToSpawn( Generator.random( Generator.Category.FOOD ) );
if (Dungeon.posNeeded()) {
addItemToSpawn( new PotionOfStrength() );
Dungeon.potionOfStrength++;
Dungeon.limitedDrops.strengthPotions.count++;
}
if (Dungeon.soeNeeded()) {
addItemToSpawn( new ScrollOfUpgrade() );
Dungeon.scrollsOfUpgrade++;
Dungeon.limitedDrops.upgradeScrolls.count++;
}
if (Dungeon.asNeeded()) {
addItemToSpawn( new Stylus() );
Dungeon.arcaneStyli++;
Dungeon.limitedDrops.arcaneStyli.count++;
}
int bonus = 0;
@ -571,7 +571,8 @@ public abstract class Level implements Bundlable {
if ((Dungeon.isChallenged( Challenges.NO_FOOD ) && (item instanceof Food || item instanceof BlandfruitBush.Seed)) ||
(Dungeon.isChallenged( Challenges.NO_ARMOR ) && item instanceof Armor) ||
(Dungeon.isChallenged( Challenges.NO_HEALING ) && item instanceof PotionOfHealing) ||
(Dungeon.isChallenged( Challenges.NO_HERBALISM ) && (item instanceof Plant.Seed || item instanceof Dewdrop))) {
(Dungeon.isChallenged( Challenges.NO_HERBALISM ) && (item instanceof Plant.Seed || item instanceof Dewdrop)) ||
item == null) {
Heap heap = new Heap();
GameScene.add( heap );

View File

@ -28,9 +28,12 @@ import com.shatteredpixel.shatteredpixeldungeon.effects.CellEmitter;
import com.shatteredpixel.shatteredpixeldungeon.effects.particles.LeafParticle;
import com.shatteredpixel.shatteredpixeldungeon.items.Dewdrop;
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.artifacts.SandalsOfNature;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.Terrain;
import com.shatteredpixel.shatteredpixeldungeon.plants.BlandfruitBush;
import com.shatteredpixel.shatteredpixeldungeon.plants.Plant;
import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene;
import com.watabou.utils.Random;
@ -59,7 +62,15 @@ public class HighGrass {
if (naturalismLevel >= 0) {
// Seed
if (Random.Int(18 - ((int) (naturalismLevel * 3.34))) == 0) {
level.drop(Generator.random(Generator.Category.SEED), pos).sprite.drop();
Item seed = Generator.random(Generator.Category.SEED);
if (seed instanceof BlandfruitBush.Seed) {
if (Random.Int(15) - Dungeon.limitedDrops.blandfruitSeed.count >= 0) {
level.drop(seed, pos).sprite.drop();
Dungeon.limitedDrops.blandfruitSeed.count++;
}
} else
level.drop(seed, pos).sprite.drop();
}
// Dew

View File

@ -76,7 +76,15 @@ public class Plant implements Bundlable {
}
if (Random.Int( 5 - (naturalismLevel/2) ) == 0) {
Dungeon.level.drop( Generator.random( Generator.Category.SEED ), pos ).sprite.drop();
Item seed = Generator.random(Generator.Category.SEED);
if (seed instanceof BlandfruitBush.Seed) {
if (Random.Int(15) - Dungeon.limitedDrops.blandfruitSeed.count >= 0) {
Dungeon.level.drop(seed, pos).sprite.drop();
Dungeon.limitedDrops.blandfruitSeed.count++;
}
} else
Dungeon.level.drop(seed, pos).sprite.drop();
}
if (Random.Int( 5 - naturalismLevel ) == 0) {
Dungeon.level.drop( new Dewdrop(), pos ).sprite.drop();