From 3966f420db9a25979c75e0b6b79fd262a0039cad Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Mon, 17 Mar 2014 02:37:57 -0400 Subject: [PATCH] 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. --- .../dungeon/pack/DungeonPack.java | 6 +- .../mod_pocketDim/helpers/DungeonHelper.java | 61 +++++++++++-------- .../mod_pocketDim/world/PocketBuilder.java | 35 ++++------- 3 files changed, 52 insertions(+), 50 deletions(-) diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/pack/DungeonPack.java b/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/pack/DungeonPack.java index 44ea2d1f..6c426d21 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/pack/DungeonPack.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/pack/DungeonPack.java @@ -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 history = DungeonHelper.getDungeonChainHistory(dimension, this, maxSearchLength); + ArrayList history = DungeonHelper.getDungeonChainHistory(parent, this, maxSearchLength); ArrayList subtreeHistory; /*if (config.getDuplicateSearchLevels() > 0) { subtreeHistory = DungeonHelper.getFlatDungeonTree( - DungeonHelper.getAncestor(dimension, config.getDuplicateSearchLevels()), + DungeonHelper.getAncestor(parent, config.getDuplicateSearchLevels()), MAX_SUBTREE_LIST_SIZE); } else diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java b/src/main/java/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java index 419ffcd9..e2d601bd 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java @@ -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 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 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(); - } int count = 0; - NewDimData tail = dimension.parent(); - DungeonData dungeon = tail.dungeon(); + NewDimData current = start; + DungeonData dungeon = current.dungeon(); ArrayList history = new ArrayList(); 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 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 listDungeonsInTree(NewDimData root, int maxSize) { - NewDimData root = dimension; ArrayList dungeons = new ArrayList(); Queue pendingDimensions = new LinkedList(); diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketBuilder.java b/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketBuilder.java index c384ec48..877837f2 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketBuilder.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/world/PocketBuilder.java @@ -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 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 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 selectDungeon(NewDimData dimension, Random random, DDProperties properties) + private static Pair 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) {