From 9a59fc8a9be2ff1e76ce4d70ba2459da485c92e3 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Fri, 15 May 2020 23:21:13 -0400 Subject: [PATCH] v0.8.1: Added a deck system for probabilities of standard consumables --- .../shatteredpixeldungeon/Dungeon.java | 1 - .../actors/mobs/Warlock.java | 3 +- .../items/Generator.java | 691 +++++++++--------- .../items/armor/curses/Overgrowth.java | 4 +- .../items/artifacts/UnstableSpellbook.java | 4 +- .../items/bombs/RegrowthBomb.java | 2 +- .../items/potions/Potion.java | 7 +- .../items/wands/CursedWand.java | 2 +- .../items/wands/WandOfRegrowth.java | 2 +- .../weapon/missiles/darts/TippedDart.java | 2 +- .../rooms/secret/SecretLibraryRoom.java | 6 +- .../levels/rooms/special/ShopRoom.java | 11 +- .../levels/rooms/standard/PlantsRoom.java | 2 +- 13 files changed, 389 insertions(+), 348 deletions(-) diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java index a9c2da549..b0429e9ea 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java @@ -207,7 +207,6 @@ public class Dungeon { Imp.Quest.reset(); Generator.reset(); - Generator.initArtifacts(); hero = new Hero(); hero.live(); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Warlock.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Warlock.java index 46485b92a..905f4bea0 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Warlock.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Warlock.java @@ -134,12 +134,13 @@ public class Warlock extends Mob implements Callback { } @Override + //TODO refactor warlock drops, they shouldn't pull from regular healing potion pool public Item createLoot(){ Item loot = super.createLoot(); if (loot instanceof PotionOfHealing){ - //count/10 chance of not dropping potion + //count/8 chance of not dropping potion if (Random.Float() < ((8f - Dungeon.LimitedDrops.WARLOCK_HP.count) / 8f)){ Dungeon.LimitedDrops.WARLOCK_HP.count++; } else { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Generator.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Generator.java index d4285da05..f4dc6b22b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Generator.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Generator.java @@ -178,279 +178,7 @@ import java.util.LinkedHashMap; public class Generator { - public enum Category { - WEAPON ( 6, MeleeWeapon.class), - WEP_T1 ( 0, MeleeWeapon.class), - WEP_T2 ( 0, MeleeWeapon.class), - WEP_T3 ( 0, MeleeWeapon.class), - WEP_T4 ( 0, MeleeWeapon.class), - WEP_T5 ( 0, MeleeWeapon.class), - - ARMOR ( 4, Armor.class ), - - MISSILE ( 3, MissileWeapon.class ), - MIS_T1 ( 0, MissileWeapon.class ), - MIS_T2 ( 0, MissileWeapon.class ), - MIS_T3 ( 0, MissileWeapon.class ), - MIS_T4 ( 0, MissileWeapon.class ), - MIS_T5 ( 0, MissileWeapon.class ), - - WAND ( 3, Wand.class ), - RING ( 1, Ring.class ), - ARTIFACT( 1, Artifact.class), - - FOOD ( 0, Food.class ), - - POTION ( 20, Potion.class ), - SEED ( 0, Plant.Seed.class ), //dropped by grass - - SCROLL ( 20, Scroll.class ), - STONE ( 2, Runestone.class), - - GOLD ( 18, Gold.class ); - - public Class[] classes; - public float[] probs; - - public float prob; - public Class superClass; - - private Category( float prob, Class superClass ) { - this.prob = prob; - this.superClass = superClass; - } - - public static int order( Item item ) { - for (int i=0; i < values().length; i++) { - if (values()[i].superClass.isInstance( item )) { - return i; - } - } - - return item instanceof Bag ? Integer.MAX_VALUE : Integer.MAX_VALUE - 1; - } - - private static final float[] INITIAL_ARTIFACT_PROBS = new float[]{ 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}; - - static { - GOLD.classes = new Class[]{ - Gold.class }; - GOLD.probs = new float[]{ 1 }; - - POTION.classes = new Class[]{ - PotionOfStrength.class, //2 drop every chapter, see Dungeon.posNeeded() - PotionOfHealing.class, - PotionOfMindVision.class, - PotionOfFrost.class, - PotionOfLiquidFlame.class, - PotionOfToxicGas.class, - PotionOfHaste.class, - PotionOfInvisibility.class, - PotionOfLevitation.class, - PotionOfParalyticGas.class, - PotionOfPurity.class, - PotionOfExperience.class}; - POTION.probs = new float[]{ 0, 6, 4, 3, 3, 3, 2, 2, 2, 2, 2, 1 }; - - SEED.classes = new Class[]{ - Rotberry.Seed.class, //quest item - Blindweed.Seed.class, - Dreamfoil.Seed.class, - Earthroot.Seed.class, - Fadeleaf.Seed.class, - Firebloom.Seed.class, - Icecap.Seed.class, - Sorrowmoss.Seed.class, - Stormvine.Seed.class, - Sungrass.Seed.class, - Swiftthistle.Seed.class, - Starflower.Seed.class}; - SEED.probs = new float[]{ 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 1 }; - - SCROLL.classes = new Class[]{ - ScrollOfUpgrade.class, //3 drop every chapter, see Dungeon.souNeeded() - ScrollOfIdentify.class, - ScrollOfRemoveCurse.class, - ScrollOfMirrorImage.class, - ScrollOfRecharging.class, - ScrollOfTeleportation.class, - ScrollOfLullaby.class, - ScrollOfMagicMapping.class, - ScrollOfRage.class, - ScrollOfRetribution.class, - ScrollOfTerror.class, - ScrollOfTransmutation.class - }; - SCROLL.probs = new float[]{ 0, 6, 4, 3, 3, 3, 2, 2, 2, 2, 2, 1 }; - - STONE.classes = new Class[]{ - StoneOfEnchantment.class, //1 is guaranteed to drop on floors 6-19 - StoneOfAugmentation.class, //1 is sold in each shop - StoneOfIntuition.class, //1 additional stone is also dropped on floors 1-3 - StoneOfAggression.class, - StoneOfAffection.class, - StoneOfBlast.class, - StoneOfBlink.class, - StoneOfClairvoyance.class, - StoneOfDeepenedSleep.class, - StoneOfDisarming.class, - StoneOfFlock.class, - StoneOfShock.class - }; - STONE.probs = new float[]{ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; - - WAND.classes = new Class[]{ - WandOfMagicMissile.class, - WandOfLightning.class, - WandOfDisintegration.class, - WandOfFireblast.class, - WandOfCorrosion.class, - WandOfBlastWave.class, - WandOfLivingEarth.class, - WandOfFrost.class, - WandOfPrismaticLight.class, - WandOfWarding.class, - WandOfTransfusion.class, - WandOfCorruption.class, - WandOfRegrowth.class }; - WAND.probs = new float[]{ 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3 }; - - //see generator.randomWeapon - WEAPON.classes = new Class[]{}; - WEAPON.probs = new float[]{}; - - WEP_T1.classes = new Class[]{ - WornShortsword.class, - Gloves.class, - Dagger.class, - MagesStaff.class - }; - WEP_T1.probs = new float[]{ 1, 1, 1, 0 }; - - WEP_T2.classes = new Class[]{ - Shortsword.class, - HandAxe.class, - Spear.class, - Quarterstaff.class, - Dirk.class - }; - WEP_T2.probs = new float[]{ 6, 5, 5, 4, 4 }; - - WEP_T3.classes = new Class[]{ - Sword.class, - Mace.class, - Scimitar.class, - RoundShield.class, - Sai.class, - Whip.class - }; - WEP_T3.probs = new float[]{ 6, 5, 5, 4, 4, 4 }; - - WEP_T4.classes = new Class[]{ - Longsword.class, - BattleAxe.class, - Flail.class, - RunicBlade.class, - AssassinsBlade.class, - Crossbow.class - }; - WEP_T4.probs = new float[]{ 6, 5, 5, 4, 4, 4 }; - - WEP_T5.classes = new Class[]{ - Greatsword.class, - WarHammer.class, - Glaive.class, - Greataxe.class, - Greatshield.class, - Gauntlet.class - }; - WEP_T5.probs = new float[]{ 6, 5, 5, 4, 4, 4 }; - - //see Generator.randomArmor - ARMOR.classes = new Class[]{ - ClothArmor.class, - LeatherArmor.class, - MailArmor.class, - ScaleArmor.class, - PlateArmor.class }; - ARMOR.probs = new float[]{ 0, 0, 0, 0, 0 }; - - //see Generator.randomMissile - MISSILE.classes = new Class[]{}; - MISSILE.probs = new float[]{}; - - MIS_T1.classes = new Class[]{ - ThrowingStone.class, - ThrowingKnife.class - }; - MIS_T1.probs = new float[]{ 6, 5 }; - - MIS_T2.classes = new Class[]{ - FishingSpear.class, - ThrowingClub.class, - Shuriken.class - }; - MIS_T2.probs = new float[]{ 6, 5, 4 }; - - MIS_T3.classes = new Class[]{ - ThrowingSpear.class, - Kunai.class, - Bolas.class - }; - MIS_T3.probs = new float[]{ 6, 5, 4 }; - - MIS_T4.classes = new Class[]{ - Javelin.class, - Tomahawk.class, - HeavyBoomerang.class - }; - MIS_T4.probs = new float[]{ 6, 5, 4 }; - - MIS_T5.classes = new Class[]{ - Trident.class, - ThrowingHammer.class, - ForceCube.class - }; - MIS_T5.probs = new float[]{ 6, 5, 4 }; - - FOOD.classes = new Class[]{ - Food.class, - Pasty.class, - MysteryMeat.class }; - FOOD.probs = new float[]{ 4, 1, 0 }; - - RING.classes = new Class[]{ - RingOfAccuracy.class, - RingOfEvasion.class, - RingOfElements.class, - RingOfForce.class, - RingOfFuror.class, - RingOfHaste.class, - RingOfEnergy.class, - RingOfMight.class, - RingOfSharpshooting.class, - RingOfTenacity.class, - RingOfWealth.class}; - RING.probs = new float[]{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; - - ARTIFACT.classes = new Class[]{ - CapeOfThorns.class, - ChaliceOfBlood.class, - CloakOfShadows.class, - HornOfPlenty.class, - MasterThievesArmband.class, - SandalsOfNature.class, - TalismanOfForesight.class, - TimekeepersHourglass.class, - UnstableSpellbook.class, - AlchemistsToolkit.class, - DriedRose.class, - LloydsBeacon.class, - EtherealChains.class - }; - ARTIFACT.probs = INITIAL_ARTIFACT_PROBS.clone(); - } - } + private static final String CATEGORY_PROBS = "_probs"; private static final float[][] floorSetTierProbs = new float[][] { {0, 70, 20, 8, 2}, @@ -465,8 +193,13 @@ public class Generator { public static void reset() { for (Category cat : Category.values()) { categoryProbs.put( cat, cat.prob ); + if (cat.defaultProbs != null) cat.probs = cat.defaultProbs.clone(); } } + + public static void reset(Category cat){ + cat.probs = cat.defaultProbs.clone(); + } public static Item random() { Category cat = Random.chances( categoryProbs ); @@ -480,18 +213,33 @@ public class Generator { public static Item random( Category cat ) { switch (cat) { - case ARMOR: - return randomArmor(); - case WEAPON: - return randomWeapon(); - case MISSILE: - return randomMissile(); - case ARTIFACT: - Item item = randomArtifact(); - //if we're out of artifacts, return a ring instead. - return item != null ? item : random(Category.RING); - default: - return ((Item) Reflection.newInstance(cat.classes[Random.chances( cat.probs )])).random(); + case ARMOR: + return randomArmor(); + case WEAPON: + return randomWeapon(); + case MISSILE: + return randomMissile(); + case ARTIFACT: + Item item = randomArtifact(); + //if we're out of artifacts, return a ring instead. + return item != null ? item : random(Category.RING); + default: + int i = Random.chances(cat.probs); + if (i == -1) { + reset(cat); + i = Random.chances(cat.probs); + } + if (cat.defaultProbs != null) cat.probs[i]--; + return ((Item) Reflection.newInstance(cat.classes[i])).random(); + } + } + + //overrides any deck systems and always uses default probs + public static Item randomUsingDefaults( Category cat ){ + if (cat.defaultProbs == null) { + return random(cat); //currently covers weapons/armor/missiles + } else { + return ((Item) Reflection.newInstance(cat.classes[Random.chances(cat.defaultProbs)])).random(); } } @@ -566,47 +314,25 @@ public class Generator { if (i == -1){ return null; } - - Class art = (Class) cat.classes[i]; - if (removeArtifact(art)) { - Artifact artifact = Reflection.newInstance(art); - artifact.random(); - return artifact; - } else { - return null; - } + cat.probs[i]--; + return (Artifact) Reflection.newInstance((Class) cat.classes[i]).random(); + } public static boolean removeArtifact(Class artifact) { - if (spawnedArtifacts.contains(artifact)) - return false; - Category cat = Category.ARTIFACT; - for (int i = 0; i < cat.classes.length; i++) + for (int i = 0; i < cat.classes.length; i++){ if (cat.classes[i].equals(artifact)) { - if (cat.probs[i] == 1){ - cat.probs[i] = 0; - spawnedArtifacts.add(artifact); - return true; - } else - return false; + cat.probs[i] = 0; + return true; } - + } return false; } - //resets artifact probabilities, for new dungeons - public static void initArtifacts() { - Category.ARTIFACT.probs = Category.INITIAL_ARTIFACT_PROBS.clone(); - spawnedArtifacts = new ArrayList<>(); - } - - private static ArrayList> spawnedArtifacts = new ArrayList<>(); - private static final String GENERAL_PROBS = "general_probs"; - private static final String SPAWNED_ARTIFACTS = "spawned_artifacts"; - + public static void storeInBundle(Bundle bundle) { Float[] genProbs = categoryProbs.values().toArray(new Float[0]); float[] storeProbs = new float[genProbs.length]; @@ -614,25 +340,338 @@ public class Generator { storeProbs[i] = genProbs[i]; } bundle.put( GENERAL_PROBS, storeProbs); - - bundle.put( SPAWNED_ARTIFACTS, spawnedArtifacts.toArray(new Class[0])); - } + for (Category cat : Category.values()){ + if (cat.defaultProbs == null) continue; + boolean needsStore = false; + for (int i = 0; i < cat.probs.length; i++){ + if (cat.probs[i] != cat.defaultProbs[i]){ + needsStore = true; + break; + } + } + + if (needsStore){ + bundle.put(cat.name().toLowerCase() + CATEGORY_PROBS, cat.probs); + } + } + } + public static void restoreFromBundle(Bundle bundle) { + reset(); + if (bundle.contains(GENERAL_PROBS)){ float[] probs = bundle.getFloatArray(GENERAL_PROBS); for (int i = 0; i < probs.length; i++){ categoryProbs.put(Category.values()[i], probs[i]); } - } else { - reset(); } - - initArtifacts(); - - for ( Class artifact : bundle.getClassArray(SPAWNED_ARTIFACTS) ){ - removeArtifact(artifact); + + for (Category cat : Category.values()){ + if (bundle.contains(cat.name().toLowerCase() + CATEGORY_PROBS)){ + float[] probs = bundle.getFloatArray(cat.name().toLowerCase() + CATEGORY_PROBS); + if (cat.defaultProbs != null && probs.length == cat.defaultProbs.length){ + cat.probs = probs; + } + } } - + + //pre-0.8.1 + if (bundle.contains("spawned_artifacts")) { + for (Class artifact : bundle.getClassArray("spawned_artifacts")) { + Category cat = Category.ARTIFACT; + for (int i = 0; i < cat.classes.length; i++) { + if (cat.classes[i].equals(artifact)) { + cat.probs[i] = 0; + } + } + } + } + + } + + public enum Category { + WEAPON ( 6, MeleeWeapon.class), + WEP_T1 ( 0, MeleeWeapon.class), + WEP_T2 ( 0, MeleeWeapon.class), + WEP_T3 ( 0, MeleeWeapon.class), + WEP_T4 ( 0, MeleeWeapon.class), + WEP_T5 ( 0, MeleeWeapon.class), + + ARMOR ( 4, Armor.class ), + + MISSILE ( 3, MissileWeapon.class ), + MIS_T1 ( 0, MissileWeapon.class ), + MIS_T2 ( 0, MissileWeapon.class ), + MIS_T3 ( 0, MissileWeapon.class ), + MIS_T4 ( 0, MissileWeapon.class ), + MIS_T5 ( 0, MissileWeapon.class ), + + WAND ( 3, Wand.class ), + RING ( 1, Ring.class ), + ARTIFACT( 1, Artifact.class), + + FOOD ( 0, Food.class ), + + POTION ( 20, Potion.class ), + SEED ( 0, Plant.Seed.class ), //dropped by grass + + SCROLL ( 20, Scroll.class ), + STONE ( 2, Runestone.class), + + GOLD ( 18, Gold.class ); + + public Class[] classes; + + static { + GOLD.classes = new Class[]{ + Gold.class }; + GOLD.probs = new float[]{ 1 }; + + POTION.classes = new Class[]{ + PotionOfStrength.class, //2 drop every chapter, see Dungeon.posNeeded() + PotionOfHealing.class, + PotionOfMindVision.class, + PotionOfFrost.class, + PotionOfLiquidFlame.class, + PotionOfToxicGas.class, + PotionOfHaste.class, + PotionOfInvisibility.class, + PotionOfLevitation.class, + PotionOfParalyticGas.class, + PotionOfPurity.class, + PotionOfExperience.class}; + POTION.defaultProbs = new float[]{ 0, 6, 4, 3, 3, 3, 2, 2, 2, 2, 2, 1 }; + POTION.probs = POTION.defaultProbs.clone(); + + SEED.classes = new Class[]{ + Rotberry.Seed.class, //quest item + Sungrass.Seed.class, + Fadeleaf.Seed.class, + Icecap.Seed.class, + Firebloom.Seed.class, + Sorrowmoss.Seed.class, + Swiftthistle.Seed.class, + Blindweed.Seed.class, + Stormvine.Seed.class, + Earthroot.Seed.class, + Dreamfoil.Seed.class, + Starflower.Seed.class}; + //TODO adjust these + SEED.defaultProbs = new float[]{ 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 1 }; + SEED.probs = SEED.defaultProbs.clone(); + + SCROLL.classes = new Class[]{ + ScrollOfUpgrade.class, //3 drop every chapter, see Dungeon.souNeeded() + ScrollOfIdentify.class, + ScrollOfRemoveCurse.class, + ScrollOfMirrorImage.class, + ScrollOfRecharging.class, + ScrollOfTeleportation.class, + ScrollOfLullaby.class, + ScrollOfMagicMapping.class, + ScrollOfRage.class, + ScrollOfRetribution.class, + ScrollOfTerror.class, + ScrollOfTransmutation.class + }; + SCROLL.defaultProbs = new float[]{ 0, 6, 4, 3, 3, 3, 2, 2, 2, 2, 2, 1 }; + SCROLL.probs = SCROLL.defaultProbs.clone(); + + STONE.classes = new Class[]{ + StoneOfEnchantment.class, //1 is guaranteed to drop on floors 6-19 + StoneOfIntuition.class, //1 additional stone is also dropped on floors 1-3 + StoneOfDisarming.class, + StoneOfFlock.class, + StoneOfShock.class, + StoneOfBlink.class, + StoneOfDeepenedSleep.class, + StoneOfClairvoyance.class, + StoneOfAggression.class, + StoneOfBlast.class, + StoneOfAffection.class, + StoneOfAugmentation.class //1 is also sold in each shop + }; + //TODO adjust these + STONE.defaultProbs = new float[]{ 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0 }; + STONE.probs = STONE.defaultProbs.clone(); + + WAND.classes = new Class[]{ + WandOfMagicMissile.class, + WandOfLightning.class, + WandOfDisintegration.class, + WandOfFireblast.class, + WandOfCorrosion.class, + WandOfBlastWave.class, + WandOfLivingEarth.class, + WandOfFrost.class, + WandOfPrismaticLight.class, + WandOfWarding.class, + WandOfTransfusion.class, + WandOfCorruption.class, + WandOfRegrowth.class }; + WAND.probs = new float[]{ 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3 }; + + //see generator.randomWeapon + WEAPON.classes = new Class[]{}; + WEAPON.probs = new float[]{}; + + WEP_T1.classes = new Class[]{ + WornShortsword.class, + Gloves.class, + Dagger.class, + MagesStaff.class + }; + WEP_T1.probs = new float[]{ 1, 1, 1, 0 }; + + WEP_T2.classes = new Class[]{ + Shortsword.class, + HandAxe.class, + Spear.class, + Quarterstaff.class, + Dirk.class + }; + WEP_T2.probs = new float[]{ 6, 5, 5, 4, 4 }; + + WEP_T3.classes = new Class[]{ + Sword.class, + Mace.class, + Scimitar.class, + RoundShield.class, + Sai.class, + Whip.class + }; + WEP_T3.probs = new float[]{ 6, 5, 5, 4, 4, 4 }; + + WEP_T4.classes = new Class[]{ + Longsword.class, + BattleAxe.class, + Flail.class, + RunicBlade.class, + AssassinsBlade.class, + Crossbow.class + }; + WEP_T4.probs = new float[]{ 6, 5, 5, 4, 4, 4 }; + + WEP_T5.classes = new Class[]{ + Greatsword.class, + WarHammer.class, + Glaive.class, + Greataxe.class, + Greatshield.class, + Gauntlet.class + }; + WEP_T5.probs = new float[]{ 6, 5, 5, 4, 4, 4 }; + + //see Generator.randomArmor + ARMOR.classes = new Class[]{ + ClothArmor.class, + LeatherArmor.class, + MailArmor.class, + ScaleArmor.class, + PlateArmor.class }; + ARMOR.probs = new float[]{ 0, 0, 0, 0, 0 }; + + //see Generator.randomMissile + MISSILE.classes = new Class[]{}; + MISSILE.probs = new float[]{}; + + MIS_T1.classes = new Class[]{ + ThrowingStone.class, + ThrowingKnife.class + }; + MIS_T1.probs = new float[]{ 6, 5 }; + + MIS_T2.classes = new Class[]{ + FishingSpear.class, + ThrowingClub.class, + Shuriken.class + }; + MIS_T2.probs = new float[]{ 6, 5, 4 }; + + MIS_T3.classes = new Class[]{ + ThrowingSpear.class, + Kunai.class, + Bolas.class + }; + MIS_T3.probs = new float[]{ 6, 5, 4 }; + + MIS_T4.classes = new Class[]{ + Javelin.class, + Tomahawk.class, + HeavyBoomerang.class + }; + MIS_T4.probs = new float[]{ 6, 5, 4 }; + + MIS_T5.classes = new Class[]{ + Trident.class, + ThrowingHammer.class, + ForceCube.class + }; + MIS_T5.probs = new float[]{ 6, 5, 4 }; + + FOOD.classes = new Class[]{ + Food.class, + Pasty.class, + MysteryMeat.class }; + FOOD.probs = new float[]{ 4, 1, 0 }; + + RING.classes = new Class[]{ + RingOfAccuracy.class, + RingOfEvasion.class, + RingOfElements.class, + RingOfForce.class, + RingOfFuror.class, + RingOfHaste.class, + RingOfEnergy.class, + RingOfMight.class, + RingOfSharpshooting.class, + RingOfTenacity.class, + RingOfWealth.class}; + RING.probs = new float[]{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; + + ARTIFACT.classes = new Class[]{ + CapeOfThorns.class, + ChaliceOfBlood.class, + CloakOfShadows.class, + HornOfPlenty.class, + MasterThievesArmband.class, + SandalsOfNature.class, + TalismanOfForesight.class, + TimekeepersHourglass.class, + UnstableSpellbook.class, + AlchemistsToolkit.class, + DriedRose.class, + LloydsBeacon.class, + EtherealChains.class + }; + ARTIFACT.defaultProbs = new float[]{ 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}; + ARTIFACT.probs = ARTIFACT.defaultProbs.clone(); + } + + //some item types use a deck-based system, where the probs decrement as items are picked + // until they are all 0, and then they reset. Those generator classes should define + // defaultProbs. If defaultProbs is null then a deck system isn't used. + //Artifacts in particular don't reset, no duplicates! + public float[] probs; + + public float prob; + public Class superClass; + + private Category( float prob, Class superClass ) { + this.prob = prob; + this.superClass = superClass; + } + + public static int order( Item item ) { + for (int i=0; i < values().length; i++) { + if (values()[i].superClass.isInstance( item )) { + return i; + } + } + + return item instanceof Bag ? Integer.MAX_VALUE : Integer.MAX_VALUE - 1; + } + public float[] defaultProbs = null; } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/curses/Overgrowth.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/curses/Overgrowth.java index 1bcc1efd9..363e4d0bd 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/curses/Overgrowth.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/armor/curses/Overgrowth.java @@ -45,8 +45,8 @@ public class Overgrowth extends Armor.Glyph { Plant.Seed s; do{ - s = (Plant.Seed) Generator.random(Generator.Category.SEED); - } while (s instanceof BlandfruitBush.Seed || s instanceof Starflower.Seed); + s = (Plant.Seed) Generator.randomUsingDefaults(Generator.Category.SEED); + } while (s instanceof Starflower.Seed); Plant p = s.couch(defender.pos, null); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/UnstableSpellbook.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/UnstableSpellbook.java index 505c3689b..492f995cd 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/UnstableSpellbook.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/artifacts/UnstableSpellbook.java @@ -78,7 +78,7 @@ public class UnstableSpellbook extends Artifact { super(); Class[] scrollClasses = Generator.Category.SCROLL.classes; - float[] probs = Generator.Category.SCROLL.probs.clone(); //array of primitives, clone gives deep copy. + float[] probs = Generator.Category.SCROLL.defaultProbs.clone(); //array of primitives, clone gives deep copy. int i = Random.chances(probs); while (i != -1){ @@ -116,7 +116,7 @@ public class UnstableSpellbook extends Artifact { Scroll scroll; do { - scroll = (Scroll) Generator.random(Generator.Category.SCROLL); + scroll = (Scroll) Generator.randomUsingDefaults(Generator.Category.SCROLL); } while (scroll == null //reduce the frequency of these scrolls by half ||((scroll instanceof ScrollOfIdentify || diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/bombs/RegrowthBomb.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/bombs/RegrowthBomb.java index b94d3e5eb..a3808b40a 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/bombs/RegrowthBomb.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/bombs/RegrowthBomb.java @@ -93,7 +93,7 @@ public class RegrowthBomb extends Bomb { for (int i = 0; i < plants; i++) { Integer plantPos = Random.element(plantCandidates); if (plantPos != null) { - Dungeon.level.plant((Plant.Seed) Generator.random(Generator.Category.SEED), plantPos); + Dungeon.level.plant((Plant.Seed) Generator.randomUsingDefaults(Generator.Category.SEED), plantPos); plantCandidates.remove(plantPos); } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/potions/Potion.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/potions/Potion.java index b2499e7eb..28a32875b 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/potions/Potion.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/potions/Potion.java @@ -507,7 +507,7 @@ public class Potion extends Item { if ( (seeds.size() == 2 && Random.Int(4) == 0) || (seeds.size() == 3 && Random.Int(2) == 0)) { - result = Generator.random( Generator.Category.POTION ); + result = Generator.randomUsingDefaults( Generator.Category.POTION ); } else { result = Reflection.newInstance(types.get(Random.element(ingredients).getClass())); @@ -517,11 +517,12 @@ public class Potion extends Item { if (seeds.size() == 1){ result.identify(); } - + while (result instanceof PotionOfHealing && (Dungeon.isChallenged(Challenges.NO_HEALING) || Random.Int(10) < Dungeon.LimitedDrops.COOKING_HP.count)) { - result = Generator.random(Generator.Category.POTION); + + result = Generator.randomUsingDefaults(Generator.Category.POTION); } if (result instanceof PotionOfHealing) { diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/CursedWand.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/CursedWand.java index 93224a3d7..eab5d82a7 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/CursedWand.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/CursedWand.java @@ -198,7 +198,7 @@ public class CursedWand { pos == Terrain.GRASS || pos == Terrain.HIGH_GRASS || pos == Terrain.FURROWED_GRASS) { - Dungeon.level.plant((Plant.Seed) Generator.random(Generator.Category.SEED), pos); + Dungeon.level.plant((Plant.Seed) Generator.randomUsingDefaults(Generator.Category.SEED), pos); } afterZap.call(); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfRegrowth.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfRegrowth.java index 68cda5bea..3c4afff29 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfRegrowth.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/wands/WandOfRegrowth.java @@ -159,7 +159,7 @@ public class WandOfRegrowth extends Wand { Level floor = Dungeon.level; while(cells.hasNext() && Random.Float() <= numPlants){ - Plant.Seed seed = (Plant.Seed) Generator.random(Generator.Category.SEED); + Plant.Seed seed = (Plant.Seed) Generator.randomUsingDefaults(Generator.Category.SEED); floor.plant(seed, cells.next()); numPlants --; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/TippedDart.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/TippedDart.java index 9ea270399..059838132 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/TippedDart.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/weapon/missiles/darts/TippedDart.java @@ -162,7 +162,7 @@ public abstract class TippedDart extends Dart { public static TippedDart randomTipped( int quantity ){ Plant.Seed s; do{ - s = (Plant.Seed) Generator.random(Generator.Category.SEED); + s = (Plant.Seed) Generator.randomUsingDefaults(Generator.Category.SEED); } while (!types.containsKey(s.getClass())); return getTipped(s, quantity ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/secret/SecretLibraryRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/secret/SecretLibraryRoom.java index 944bd32f4..b6c867ad7 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/secret/SecretLibraryRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/secret/SecretLibraryRoom.java @@ -57,13 +57,13 @@ public class SecretLibraryRoom extends SecretRoom { static{ scrollChances.put( ScrollOfIdentify.class, 1f ); scrollChances.put( ScrollOfRemoveCurse.class, 2f ); - scrollChances.put( ScrollOfMagicMapping.class, 3f ); scrollChances.put( ScrollOfMirrorImage.class, 3f ); scrollChances.put( ScrollOfRecharging.class, 3f ); + scrollChances.put( ScrollOfTeleportation.class, 3f ); scrollChances.put( ScrollOfLullaby.class, 4f ); - scrollChances.put( ScrollOfRetribution.class, 4f ); + scrollChances.put( ScrollOfMagicMapping.class, 4f ); scrollChances.put( ScrollOfRage.class, 4f ); - scrollChances.put( ScrollOfTeleportation.class, 4f ); + scrollChances.put( ScrollOfRetribution.class, 4f ); scrollChances.put( ScrollOfTerror.class, 4f ); scrollChances.put( ScrollOfTransmutation.class, 6f ); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/ShopRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/ShopRoom.java index 86bf81193..5eaa3cf70 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/ShopRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/special/ShopRoom.java @@ -196,18 +196,19 @@ public class ShopRoom extends SpecialRoom { itemsToSpawn.add( new PotionOfHealing() ); - for (int i=0; i < 3; i++) - itemsToSpawn.add( Generator.random( Generator.Category.POTION ) ); + itemsToSpawn.add( Generator.randomUsingDefaults( Generator.Category.POTION ) ); + itemsToSpawn.add( Generator.randomUsingDefaults( Generator.Category.POTION ) ); + itemsToSpawn.add( Generator.randomUsingDefaults( Generator.Category.POTION ) ); itemsToSpawn.add( new ScrollOfIdentify() ); itemsToSpawn.add( new ScrollOfRemoveCurse() ); itemsToSpawn.add( new ScrollOfMagicMapping() ); - itemsToSpawn.add( Generator.random( Generator.Category.SCROLL ) ); + itemsToSpawn.add( Generator.randomUsingDefaults( Generator.Category.SCROLL ) ); for (int i=0; i < 2; i++) itemsToSpawn.add( Random.Int(2) == 0 ? - Generator.random( Generator.Category.POTION ) : - Generator.random( Generator.Category.SCROLL ) ); + Generator.randomUsingDefaults( Generator.Category.POTION ) : + Generator.randomUsingDefaults( Generator.Category.SCROLL ) ); itemsToSpawn.add( new SmallRation() ); diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/PlantsRoom.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/PlantsRoom.java index 4bde5f1a2..2b336acc7 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/PlantsRoom.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/levels/rooms/standard/PlantsRoom.java @@ -99,7 +99,7 @@ public class PlantsRoom extends StandardRoom { private static Plant.Seed randomSeed(){ Plant.Seed result; do { - result = (Plant.Seed) Generator.random(Generator.Category.SEED); + result = (Plant.Seed) Generator.randomUsingDefaults(Generator.Category.SEED); } while (result instanceof Firebloom.Seed); return result; }