v0.6.1: improvements to artifact and item spawning logic

- artifact spawn logic is now better, but no changed functionality
- item spawns are now significantly more consistent throughout a run
This commit is contained in:
Evan Debenham 2017-06-13 18:30:15 -04:00
parent 113ac2daa1
commit 33a3491e1d
4 changed files with 70 additions and 49 deletions

View File

@ -156,7 +156,7 @@ public class Bones {
//Enforces artifact uniqueness //Enforces artifact uniqueness
if (item instanceof Artifact){ if (item instanceof Artifact){
if (Generator.removeArtifact((Artifact)item)) { if (Generator.removeArtifact(((Artifact)item).getClass())) {
try { try {
Artifact artifact = (Artifact)item.getClass().newInstance(); Artifact artifact = (Artifact)item.getClass().newInstance();
//caps displayed artifact level //caps displayed artifact level

View File

@ -179,6 +179,7 @@ public class Dungeon {
Blacksmith.Quest.reset(); Blacksmith.Quest.reset();
Imp.Quest.reset(); Imp.Quest.reset();
Generator.reset();
Generator.initArtifacts(); Generator.initArtifacts();
hero = new Hero(); hero = new Hero();
hero.live(); hero.live();
@ -540,8 +541,6 @@ public class Dungeon {
seed = bundle.contains( SEED ) ? bundle.getLong( SEED ) : DungeonSeed.randomSeed(); seed = bundle.contains( SEED ) ? bundle.getLong( SEED ) : DungeonSeed.randomSeed();
Generator.reset();
Actor.restoreNextID( bundle ); Actor.restoreNextID( bundle );
quickslot.reset(); quickslot.reset();

View File

@ -149,28 +149,27 @@ import com.watabou.utils.GameMath;
import com.watabou.utils.Random; import com.watabou.utils.Random;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
public class Generator { public class Generator {
public static enum Category { public static enum Category {
WEAPON ( 100, Weapon.class ), WEAPON ( 6, Weapon.class ),
WEP_T1 ( 0, Weapon.class), WEP_T1 ( 0, Weapon.class),
WEP_T2 ( 0, Weapon.class), WEP_T2 ( 0, Weapon.class),
WEP_T3 ( 0, Weapon.class), WEP_T3 ( 0, Weapon.class),
WEP_T4 ( 0, Weapon.class), WEP_T4 ( 0, Weapon.class),
WEP_T5 ( 0, Weapon.class), WEP_T5 ( 0, Weapon.class),
ARMOR ( 60, Armor.class ), ARMOR ( 4, Armor.class ),
POTION ( 500, Potion.class ), POTION ( 20, Potion.class ),
SCROLL ( 400, Scroll.class ), SCROLL ( 20, Scroll.class ),
WAND ( 40, Wand.class ), WAND ( 3, Wand.class ),
RING ( 15, Ring.class ), RING ( 1, Ring.class ),
ARTIFACT( 15, Artifact.class), ARTIFACT( 1, Artifact.class),
SEED ( 50, Plant.Seed.class ), SEED ( 0, Plant.Seed.class ),
FOOD ( 0, Food.class ), FOOD ( 0, Food.class ),
GOLD ( 500, Gold.class ); GOLD ( 25, Gold.class );
public Class<?>[] classes; public Class<?>[] classes;
public float[] probs; public float[] probs;
@ -384,14 +383,18 @@ public class Generator {
} }
public static Item random() { public static Item random() {
return random( Random.chances( categoryProbs ) ); Category cat = Random.chances( categoryProbs );
if (cat == null){
reset();
cat = Random.chances( categoryProbs );
}
categoryProbs.put( cat, categoryProbs.get( cat ) - 1);
return random( cat );
} }
public static Item random( Category cat ) { public static Item random( Category cat ) {
try { try {
categoryProbs.put( cat, categoryProbs.get( cat ) / 2 );
switch (cat) { switch (cat) {
case ARMOR: case ARMOR:
return randomArmor(); return randomArmor();
@ -482,16 +485,18 @@ public class Generator {
if (i == -1){ if (i == -1){
return null; return null;
} }
Class<?extends Artifact> art = (Class<? extends Artifact>) cat.classes[i];
Artifact artifact = (Artifact)cat.classes[i].newInstance(); if (removeArtifact(art)) {
Artifact artifact = art.newInstance();
//remove the chance of spawning this artifact.
cat.probs[i] = 0; artifact.random();
spawnedArtifacts.add(cat.classes[i].getSimpleName());
return artifact;
artifact.random(); } else {
return null;
return artifact; }
} catch (Exception e) { } catch (Exception e) {
ShatteredPixelDungeon.reportException(e); ShatteredPixelDungeon.reportException(e);
@ -499,16 +504,16 @@ public class Generator {
} }
} }
public static boolean removeArtifact(Artifact artifact) { public static boolean removeArtifact(Class<?extends Artifact> artifact) {
if (spawnedArtifacts.contains(artifact.getClass().getSimpleName())) if (spawnedArtifacts.contains(artifact))
return false; return false;
Category cat = Category.ARTIFACT; 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.getClass())) { if (cat.classes[i].equals(artifact)) {
if (cat.probs[i] == 1){ if (cat.probs[i] == 1){
cat.probs[i] = 0; cat.probs[i] = 0;
spawnedArtifacts.add(artifact.getClass().getSimpleName()); spawnedArtifacts.add(artifact);
return true; return true;
} else } else
return false; return false;
@ -524,26 +529,46 @@ public class Generator {
//checks for dried rose quest completion, adds the rose in accordingly. //checks for dried rose quest completion, adds the rose in accordingly.
if (Ghost.Quest.completed()) Category.ARTIFACT.probs[10] = 1; if (Ghost.Quest.completed()) Category.ARTIFACT.probs[10] = 1;
spawnedArtifacts = new ArrayList<String>(); spawnedArtifacts = new ArrayList<>();
} }
private static ArrayList<String> spawnedArtifacts = new ArrayList<String>(); private static ArrayList<Class<?extends Artifact>> spawnedArtifacts = new ArrayList<>();
private static final String ARTIFACTS = "artifacts"; private static final String GENERAL_PROBS = "general_probs";
private static final String SPAWNED_ARTIFACTS = "spawned_artifacts";
//used to store information on which artifacts have been spawned.
public static void storeInBundle(Bundle bundle) { public static void storeInBundle(Bundle bundle) {
bundle.put( ARTIFACTS, spawnedArtifacts.toArray(new String[spawnedArtifacts.size()])); Float[] genProbs = categoryProbs.values().toArray(new Float[0]);
float[] storeProbs = new float[genProbs.length];
for (int i = 0; i < storeProbs.length; i++){
storeProbs[i] = genProbs[i];
}
bundle.put( GENERAL_PROBS, storeProbs);
bundle.put( SPAWNED_ARTIFACTS, spawnedArtifacts.toArray(new Class[0]));
} }
public static void restoreFromBundle(Bundle bundle) { public static void restoreFromBundle(Bundle bundle) {
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(); initArtifacts();
if (bundle.contains(SPAWNED_ARTIFACTS)){
if (bundle.contains(ARTIFACTS)) { for ( Class<?extends Artifact> artifact : bundle.getClassArray(SPAWNED_ARTIFACTS) ){
Collections.addAll(spawnedArtifacts, bundle.getStringArray(ARTIFACTS)); removeArtifact(artifact);
}
//pre-0.6.1 saves
} else if (bundle.contains("artifacts")) {
String[] names = bundle.getStringArray("artifacts");
Category cat = Category.ARTIFACT; Category cat = Category.ARTIFACT;
for (String artifact : spawnedArtifacts) for (String artifact : names)
for (int i = 0; i < cat.classes.length; i++) for (int i = 0; i < cat.classes.length; i++)
if (cat.classes[i].getSimpleName().equals(artifact)) if (cat.classes[i].getSimpleName().equals(artifact))
cat.probs[i] = 0; cat.probs[i] = 0;

View File

@ -26,7 +26,6 @@ import com.shatteredpixel.shatteredpixeldungeon.Dungeon;
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon; import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
import com.shatteredpixel.shatteredpixeldungeon.Statistics; import com.shatteredpixel.shatteredpixeldungeon.Statistics;
import com.shatteredpixel.shatteredpixeldungeon.actors.Actor; import com.shatteredpixel.shatteredpixeldungeon.actors.Actor;
import com.shatteredpixel.shatteredpixeldungeon.items.Generator;
import com.shatteredpixel.shatteredpixeldungeon.levels.Level; import com.shatteredpixel.shatteredpixeldungeon.levels.Level;
import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom; import com.shatteredpixel.shatteredpixeldungeon.levels.rooms.special.SpecialRoom;
import com.shatteredpixel.shatteredpixeldungeon.messages.Messages; import com.shatteredpixel.shatteredpixeldungeon.messages.Messages;
@ -90,8 +89,6 @@ public class InterlevelScene extends PixelScene {
public void run() { public void run() {
try { try {
Generator.reset();
switch (mode) { switch (mode) {
case DESCEND: case DESCEND: