Improvements to Dungeon Selection

Changed the code for dungeon selection in various classes so that rather
than allocating and passing around the dimension where the dungeon will
be generated, we instead pass around the parent dimension. This
simplifies our code and moves us toward avoiding stray dims when dungeon
selection fails and to solving the dungeon pre-generation problem with
gateways.
This commit is contained in:
SenseiKiwi 2014-03-17 02:37:57 -04:00
parent 151f1a93a5
commit 3966f420db
3 changed files with 52 additions and 50 deletions

View file

@ -123,7 +123,7 @@ public class DungeonPack
}
}
public DungeonData getNextDungeon(NewDimData dimension, Random random)
public DungeonData getNextDungeon(NewDimData parent, Random random)
{
if (allDungeons.isEmpty())
{
@ -136,13 +136,13 @@ public class DungeonPack
//for dungeon packs that can extend arbitrarily deep. We should probably set a reasonable limit anyway.
int maxSearchLength = config.allowDuplicatesInChain() ? maxRuleLength : MAX_HISTORY_LENGTH;
ArrayList<DungeonData> history = DungeonHelper.getDungeonChainHistory(dimension, this, maxSearchLength);
ArrayList<DungeonData> history = DungeonHelper.getDungeonChainHistory(parent, this, maxSearchLength);
ArrayList<DungeonData> subtreeHistory;
/*if (config.getDuplicateSearchLevels() > 0)
{
subtreeHistory = DungeonHelper.getFlatDungeonTree(
DungeonHelper.getAncestor(dimension, config.getDuplicateSearchLevels()),
DungeonHelper.getAncestor(parent, config.getDuplicateSearchLevels()),
MAX_SUBTREE_LIST_SIZE);
}
else

View file

@ -231,10 +231,13 @@ public class DungeonHelper
return dungeonPackMapping.get(name.toUpperCase());
}
private DungeonPack getDimDungeonPack(NewDimData data)
private DungeonPack getDimDungeonPack(NewDimData dimension)
{
// TODO: Drop support for dim-based packs and switch to embedding the pack
// in the link data itself. That would solve the dungeon pre-generation issue.
DungeonPack pack;
DungeonData dungeon = data.dungeon();
DungeonData dungeon = dimension.dungeon();
if (dungeon != null)
{
pack = dungeon.dungeonType().Owner;
@ -247,7 +250,7 @@ public class DungeonHelper
}
else
{
if (data.id() == NETHER_DIMENSION_ID)
if (dimension.id() == NETHER_DIMENSION_ID)
{
pack = NetherPack;
}
@ -500,9 +503,9 @@ public class DungeonHelper
}
}
public DungeonData selectDungeon(NewDimData dimension, Random random)
public DungeonData selectNextDungeon(NewDimData parent, Random random)
{
DungeonPack pack = getDimDungeonPack(dimension.parent());
DungeonPack pack = getDimDungeonPack(parent);
DungeonData selection;
DungeonPackConfig config;
DungeonPack selectedPack;
@ -512,30 +515,30 @@ public class DungeonHelper
config = pack.getConfig();
selectedPack = pack;
//Are we allowed to switch to another dungeon pack?
// Are we allowed to switch to another dungeon pack?
if (config.allowPackChangeOut())
{
//Calculate the chance of switching to a different pack type
// Calculate the chance of switching to a different pack type
int packSwitchChance;
if (dimension.depth() == 1)
if (parent.isPocketDimension())
{
packSwitchChance = START_PACK_SWITCH_CHANCE;
packSwitchChance = MIN_PACK_SWITCH_CHANCE + parent.packDepth() * PACK_SWITCH_CHANCE_PER_LEVEL;
}
else
{
packSwitchChance = MIN_PACK_SWITCH_CHANCE + dimension.parent().packDepth() * PACK_SWITCH_CHANCE_PER_LEVEL;
packSwitchChance = START_PACK_SWITCH_CHANCE;
}
//Decide randomly whether to switch packs or not
// Decide randomly whether to switch packs or not
if (random.nextInt(MAX_PACK_SWITCH_CHANCE) < packSwitchChance)
{
//Find another pack
// Find another pack
selectedPack = getRandomDungeonPack(pack, random);
}
}
//Pick the next dungeon
selection = selectedPack.getNextDungeon(dimension, random);
selection = selectedPack.getNextDungeon(parent, random);
}
catch (Exception e)
{
@ -609,34 +612,42 @@ public class DungeonHelper
return names;
}
public static ArrayList<DungeonData> getDungeonChainHistory(NewDimData dimension, DungeonPack pack, int maxSize)
/**
* Lists all of the dungeons found by iterating through a dimension's ancestors. The search stops when a non-dungeon dimension is found or when the pack of a dungeon differs from the specified pack.
* @param start - the first dimension to include in the history
* @param pack - the pack to which any dungeons must belong in order to be listed
* @param maxSize - the maximum number of dungeons that can be listed
* @return a list of dungeons used in a given chain
*/
public static ArrayList<DungeonData> getDungeonChainHistory(NewDimData start, DungeonPack pack, int maxSize)
{
if (dimension == null)
if (start == null)
{
throw new IllegalArgumentException("dimension cannot be null.");
}
if (dimension.parent() == null)
{
return new ArrayList<DungeonData>();
}
int count = 0;
NewDimData tail = dimension.parent();
DungeonData dungeon = tail.dungeon();
NewDimData current = start;
DungeonData dungeon = current.dungeon();
ArrayList<DungeonData> history = new ArrayList<DungeonData>();
while (count < maxSize && dungeon != null && dungeon.dungeonType().Owner == pack)
{
history.add(dungeon);
tail = tail.parent();
dungeon = tail.dungeon();
current = current.parent();
dungeon = current.dungeon();
count++;
}
return history;
}
public static ArrayList<DungeonData> getFlatDungeonTree(NewDimData dimension, int maxSize)
/**
* Performs a breadth-first listing of all dungeons rooted at a specified dimension. Only dungeons from the same pack as the root will be included.
* @param root - the pocket dimension that serves as the root for the dungeon tree
* @param maxSize - the maximum number of dungeons that can be listed
* @return a list of the dungeons used in a given dungeon tree
*/
public static ArrayList<DungeonData> listDungeonsInTree(NewDimData root, int maxSize)
{
NewDimData root = dimension;
ArrayList<DungeonData> dungeons = new ArrayList<DungeonData>();
Queue<NewDimData> pendingDimensions = new LinkedList<NewDimData>();

View file

@ -186,7 +186,6 @@ public class PocketBuilder
schematic = loadAndValidateDungeon(dungeon, properties);
return PocketBuilder.buildDungeonPocket(dungeon, dimension, link, schematic, world, properties);
}
@ -206,10 +205,18 @@ public class PocketBuilder
throw new IllegalArgumentException("link cannot have a destination assigned already.");
}
//Choose a dungeon to generate
NewDimData parent = PocketManager.getDimensionData(link.source().getDimension());
Pair<DungeonData, DungeonSchematic> pair = selectNextDungeon(parent, random, properties);
if (pair == null)
{
System.err.println("Could not select a dungeon for generation!");
return false;
}
DungeonData dungeon = pair.getFirst();
DungeonSchematic schematic = pair.getSecond();
//Register a new dimension
NewDimData parent = PocketManager.getDimensionData(link.source().getDimension());
NewDimData dimension = PocketManager.registerPocket(parent, true);
//Load a world
@ -220,17 +227,7 @@ public class PocketBuilder
System.err.println("Could not initialize dimension for a dungeon!");
return false;
}
//Choose a dungeon to generate
Pair<DungeonData, DungeonSchematic> pair = selectDungeon(dimension, random, properties);
if (pair == null)
{
System.err.println("Could not select a dungeon for generation!");
return false;
}
DungeonData dungeon = pair.getFirst();
DungeonSchematic schematic = pair.getSecond();
return buildDungeonPocket(dungeon, dimension, link, schematic, world, properties);
}
@ -251,18 +248,12 @@ public class PocketBuilder
return linkDestination;
}
private static Pair<DungeonData, DungeonSchematic> selectDungeon(NewDimData dimension, Random random, DDProperties properties)
private static Pair<DungeonData, DungeonSchematic> selectNextDungeon(NewDimData parent, Random random, DDProperties properties)
{
//We assume the dimension doesn't have a dungeon assigned
if (dimension.dungeon() != null)
{
throw new IllegalArgumentException("dimension cannot have a dungeon assigned already.");
}
DungeonData dungeon = null;
DungeonSchematic schematic = null;
dungeon = DungeonHelper.instance().selectDungeon(dimension, random);
dungeon = DungeonHelper.instance().selectNextDungeon(parent, random);
if (dungeon != null)
{