diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Eye.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Eye.java index 7957acdd5..94ebfb513 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Eye.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Eye.java @@ -220,10 +220,10 @@ public class Eye extends Mob { } break; case 2: - loot = Generator.random(Generator.Category.SEED); + loot = Generator.randomUsingDefaults(Generator.Category.SEED); break; case 3: - loot = Generator.random(Generator.Category.STONE); + loot = Generator.randomUsingDefaults(Generator.Category.STONE); break; } return loot; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java index c2d0f9d41..8e740a51e 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java @@ -789,7 +789,7 @@ public abstract class Mob extends Char { Item item; if (loot instanceof Generator.Category) { - item = Generator.random( (Generator.Category)loot ); + item = Generator.randomUsingDefaults( (Generator.Category)loot ); } else if (loot instanceof Class) { 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 24ab2bd51..800b061cc 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 @@ -140,11 +140,11 @@ public class Warlock extends Mob implements Callback { Dungeon.LimitedDrops.WARLOCK_HP.count++; return new PotionOfHealing(); } else { - Item i = Generator.random(Generator.Category.POTION); + Item i = Generator.randomUsingDefaults(Generator.Category.POTION); int healingTried = 0; while (i instanceof PotionOfHealing){ healingTried++; - i = Generator.random(Generator.Category.POTION); + i = Generator.randomUsingDefaults(Generator.Category.POTION); } //return the attempted healing potion drops to the pool 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 46bd8eca3..89e6beef4 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Generator.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/Generator.java @@ -215,9 +215,14 @@ public class Generator { //Artifacts in particular don't reset, no duplicates! public float[] probs; public float[] defaultProbs = null; + //These variables are used as a part of the deck system, to ensure that drops are consistent + // regardless of when they occur (either as part of seeded levelgen, or random item drops) + public Long seed = null; + public int dropped = 0; //game has two decks of 35 items for overall category probs //one deck has a ring and extra armor, the other has an artifact and extra thrown weapon + //Note that pure random drops only happen as part of levelgen atm, so no seed is needed here public float firstProb; public float secondProb; public Class superClass; @@ -480,6 +485,10 @@ public class Generator { generalReset(); for (Category cat : Category.values()) { reset(cat); + if (cat.defaultProbs != null) { + cat.seed = Random.Long(); + cat.dropped = 0; + } } } @@ -501,7 +510,15 @@ public class Generator { cat = Random.chances( categoryProbs ); } categoryProbs.put( cat, categoryProbs.get( cat ) - 1); - return random( cat ); + + if (cat == Category.SEED) { + //We specifically use defaults for seeds here because, unlike other item categories + // their predominant source of drops is grass, not levelgen. This way the majority + // of seed drops still use a deck, but the few that are spawned by levelgen are consistent + return randomUsingDefaults(cat); + } else { + return random(cat); + } } public static Item random( Category cat ) { @@ -517,20 +534,32 @@ public class Generator { //if we're out of artifacts, return a ring instead. return item != null ? item : random(Category.RING); default: + if (cat.defaultProbs != null && cat.seed != null){ + Random.pushGenerator(cat.seed); + for (int i = 0; i < cat.dropped; i++) Random.Long(); + } + int i = Random.chances(cat.probs); if (i == -1) { reset(cat); i = Random.chances(cat.probs); } if (cat.defaultProbs != null) cat.probs[i]--; + + if (cat.defaultProbs != null && cat.seed != null){ + Random.popGenerator(); + cat.dropped++; + } + return ((Item) Reflection.newInstance(cat.classes[i])).random(); } } //overrides any deck systems and always uses default probs + // except for artifacts, which must always use a deck public static Item randomUsingDefaults( Category cat ){ - if (cat.defaultProbs == null) { - return random(cat); //currently covers weapons/armor/missiles + if (cat.defaultProbs == null || cat == Category.ARTIFACT) { + return random(cat); } else { return ((Item) Reflection.newInstance(cat.classes[Random.chances(cat.defaultProbs)])).random(); } @@ -601,8 +630,19 @@ public class Generator { public static Artifact randomArtifact() { Category cat = Category.ARTIFACT; + + if (cat.defaultProbs != null && cat.seed != null){ + Random.pushGenerator(cat.seed); + for (int i = 0; i < cat.dropped; i++) Random.Long(); + } + int i = Random.chances( cat.probs ); + if (cat.defaultProbs != null && cat.seed != null){ + Random.popGenerator(); + cat.dropped++; + } + //if no artifacts are left, return null if (i == -1){ return null; @@ -627,7 +667,9 @@ public class Generator { private static final String FIRST_DECK = "first_deck"; private static final String GENERAL_PROBS = "general_probs"; private static final String CATEGORY_PROBS = "_probs"; - + private static final String CATEGORY_SEED = "_seed"; + private static final String CATEGORY_DROPPED = "_dropped"; + public static void storeInBundle(Bundle bundle) { bundle.put(FIRST_DECK, usingFirstDeck); @@ -640,16 +682,11 @@ public class Generator { 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); + bundle.put(cat.name().toLowerCase() + CATEGORY_PROBS, cat.probs); + if (cat.seed != null) { + bundle.put(cat.name().toLowerCase() + CATEGORY_SEED, cat.seed); + bundle.put(cat.name().toLowerCase() + CATEGORY_DROPPED, cat.dropped); } } } @@ -672,6 +709,10 @@ public class Generator { if (cat.defaultProbs != null && probs.length == cat.defaultProbs.length){ cat.probs = probs; } + if (bundle.contains(cat.name().toLowerCase() + CATEGORY_SEED)){ + cat.seed = bundle.getLong(cat.name().toLowerCase() + CATEGORY_SEED); + cat.dropped = bundle.getInt(cat.name().toLowerCase() + CATEGORY_DROPPED); + } } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/food/Berry.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/food/Berry.java index d08ea1306..35115bc39 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/food/Berry.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/food/Berry.java @@ -56,7 +56,7 @@ public class Berry extends Food { super.satisfy(hero); SeedCounter counter = Buff.count(hero, SeedCounter.class, 1); if (counter.count() >= 2){ - Dungeon.level.drop(Generator.random(Generator.Category.SEED), hero.pos).sprite.drop(); + Dungeon.level.drop(Generator.randomUsingDefaults(Generator.Category.SEED), hero.pos).sprite.drop(); counter.detach(); } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/rings/RingOfWealth.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/rings/RingOfWealth.java index abe65a9b5..ee0681437 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/rings/RingOfWealth.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/rings/RingOfWealth.java @@ -197,11 +197,11 @@ public class RingOfWealth extends Ring { Item i = new Gold().random(); return i.quantity(i.quantity()/2); case 1: - return Generator.random(Generator.Category.STONE); + return Generator.randomUsingDefaults(Generator.Category.STONE); case 2: - return Generator.random(Generator.Category.POTION); + return Generator.randomUsingDefaults(Generator.Category.POTION); case 3: - return Generator.random(Generator.Category.SCROLL); + return Generator.randomUsingDefaults(Generator.Category.SCROLL); } } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/ScrollOfTransmutation.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/ScrollOfTransmutation.java index e3325043c..06da69ca2 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/ScrollOfTransmutation.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/scrolls/ScrollOfTransmutation.java @@ -266,7 +266,7 @@ public class ScrollOfTransmutation extends InventoryScroll { Plant.Seed n; do { - n = (Plant.Seed)Generator.random( Generator.Category.SEED ); + n = (Plant.Seed)Generator.randomUsingDefaults( Generator.Category.SEED ); } while (n.getClass() == s.getClass()); return n; @@ -277,7 +277,7 @@ public class ScrollOfTransmutation extends InventoryScroll { Runestone n; do { - n = (Runestone) Generator.random( Generator.Category.STONE ); + n = (Runestone) Generator.randomUsingDefaults( Generator.Category.STONE ); } while (n.getClass() == r.getClass()); return n; diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/Recycle.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/Recycle.java index a3fd2d03e..9f17ca812 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/Recycle.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/items/spells/Recycle.java @@ -64,19 +64,19 @@ public class Recycle extends InventorySpell { Item result; do { if (item instanceof Potion) { - result = Generator.random(Generator.Category.POTION); + result = Generator.randomUsingDefaults(Generator.Category.POTION); if (item instanceof ExoticPotion){ result = Reflection.newInstance(ExoticPotion.regToExo.get(result.getClass())); } } else if (item instanceof Scroll) { - result = Generator.random(Generator.Category.SCROLL); + result = Generator.randomUsingDefaults(Generator.Category.SCROLL); if (item instanceof ExoticScroll){ result = Reflection.newInstance(ExoticScroll.regToExo.get(result.getClass())); } } else if (item instanceof Plant.Seed) { - result = Generator.random(Generator.Category.SEED); + result = Generator.randomUsingDefaults(Generator.Category.SEED); } else if (item instanceof Runestone) { - result = Generator.random(Generator.Category.STONE); + result = Generator.randomUsingDefaults(Generator.Category.STONE); } else { result = TippedDart.randomTipped(1); } 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 d9726a3cc..65a05e368 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 @@ -379,7 +379,7 @@ public class WandOfRegrowth extends Wand { for (int i = 0; i < nSeeds && !candidates.isEmpty(); i++){ Integer c = Random.element(candidates); - Dungeon.level.drop(Generator.random(Generator.Category.SEED), c).sprite.drop(pos); + Dungeon.level.drop(Generator.randomUsingDefaults(Generator.Category.SEED), c).sprite.drop(pos); candidates.remove(c); }