From 1e5e8dcf2b440a8a561174025c97304f70f48004 Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Sun, 16 Mar 2014 22:44:13 -0400 Subject: [PATCH] Added Subtree Searches for Dungeon Packs Added a new setting to dungeon pack configs called "DuplicateSearchLevels", which allows us to configure how many levels up of the dungeon tree should be checked to avoid duplicating rooms used in that subtree. In other words, it lets us avoid repeating rooms used in neighboring branches of the dungeon. The setting has been added but it's not fully supported yet - some additional code is needed in DungeonHelper and it's not trivial to implement. I took a break because doing it wrong could break dungeon selection. --- .../dungeon/pack/DungeonPack.java | 34 ++++++++++++++++--- .../dungeon/pack/DungeonPackConfig.java | 12 +++++++ .../dungeon/pack/DungeonPackConfigReader.java | 15 ++++++++ .../mod_pocketDim/helpers/DungeonHelper.java | 9 ++++- src/main/resources/schematics/ruins/rules.txt | 2 ++ 5 files changed, 67 insertions(+), 5 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 af997fa..44ea2d1 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/pack/DungeonPack.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/pack/DungeonPack.java @@ -21,6 +21,7 @@ public class DungeonPack //FIXME: Do not release this code as an update without dealing with disowned types! private static final int MAX_HISTORY_LENGTH = 30; + private static final int MAX_SUBTREE_LIST_SIZE = 30; private final String name; private final HashMap nameToTypeMapping; @@ -136,15 +137,30 @@ public class DungeonPack int maxSearchLength = config.allowDuplicatesInChain() ? maxRuleLength : MAX_HISTORY_LENGTH; ArrayList history = DungeonHelper.getDungeonChainHistory(dimension, this, maxSearchLength); - return getNextDungeon(history, random); + + ArrayList subtreeHistory; + /*if (config.getDuplicateSearchLevels() > 0) + { + subtreeHistory = DungeonHelper.getFlatDungeonTree( + DungeonHelper.getAncestor(dimension, config.getDuplicateSearchLevels()), + MAX_SUBTREE_LIST_SIZE); + } + else + { + subtreeHistory = new ArrayList(); + }*/ + subtreeHistory = new ArrayList(); + + return getNextDungeon(history, subtreeHistory, random); } - private DungeonData getNextDungeon(ArrayList history, Random random) + private DungeonData getNextDungeon(ArrayList history, ArrayList subtreeHistory, Random random) { //Extract the dungeon types that have been used from history and convert them into an array of IDs int index; int[] typeHistory = new int[history.size()]; HashSet excludedDungeons = null; + boolean doExclude = !config.allowDuplicatesInChain() || !subtreeHistory.isEmpty(); for (index = 0; index < typeHistory.length; index++) { typeHistory[index] = history.get(index).dungeonType().ID; @@ -163,9 +179,19 @@ public class DungeonPack if (nextType != null) { //Initialize the set of excluded dungeons if needed - if (excludedDungeons == null && !config.allowDuplicatesInChain()) + if (excludedDungeons == null && doExclude) { - excludedDungeons = new HashSet(history); + if (config.allowDuplicatesInChain()) + { + excludedDungeons = new HashSet(subtreeHistory); + excludedDungeons.addAll(subtreeHistory); + } + else + { + excludedDungeons = new HashSet(2 * (history.size() + subtreeHistory.size())); + excludedDungeons.addAll(history); + excludedDungeons.addAll(subtreeHistory); + } } //List which dungeons are allowed diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/pack/DungeonPackConfig.java b/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/pack/DungeonPackConfig.java index 0074545..e5eaa54 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/pack/DungeonPackConfig.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/pack/DungeonPackConfig.java @@ -11,6 +11,7 @@ public class DungeonPackConfig private boolean allowPackChangeOut; private boolean distortDoorCoordinates; private int packWeight; + private int duplicateSearchLevels; private ArrayList rules; public DungeonPackConfig() { } @@ -25,6 +26,7 @@ public class DungeonPackConfig this.allowPackChangeOut = source.allowPackChangeOut; this.distortDoorCoordinates = source.distortDoorCoordinates; this.packWeight = source.packWeight; + this.duplicateSearchLevels = source.duplicateSearchLevels; this.rules = (source.rules != null) ? (ArrayList) source.rules.clone() : null; } @@ -114,6 +116,16 @@ public class DungeonPackConfig this.packWeight = packWeight; } + public int getDuplicateSearchLevels() + { + return duplicateSearchLevels; + } + + public void setDuplicateSearchLevels(int duplicateSearchLevels) + { + this.duplicateSearchLevels = duplicateSearchLevels; + } + public boolean doDistortDoorCoordinates() { return distortDoorCoordinates; diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/pack/DungeonPackConfigReader.java b/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/pack/DungeonPackConfigReader.java index e24ecc6..0f8b05c 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/pack/DungeonPackConfigReader.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/dungeon/pack/DungeonPackConfigReader.java @@ -35,6 +35,8 @@ public class DungeonPackConfigReader extends BaseConfigurationProcessor= MIN_DUPLICATE_SEARCH_LEVELS && levels <= MAX_DUPLICATE_SEARCH_LEVELS) + { + config.setDuplicateSearchLevels(levels); + } + else + { + valid = false; + } + } else { valid = false; diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java b/src/main/java/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java index 545168d..419ffcd 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/helpers/DungeonHelper.java @@ -615,7 +615,7 @@ public class DungeonHelper { throw new IllegalArgumentException("dimension cannot be null."); } - if(dimension.parent()==null) + if (dimension.parent() == null) { return new ArrayList(); } @@ -664,4 +664,11 @@ public class DungeonHelper } return dungeons; } + + public static NewDimData getAncestor(NewDimData dimension, int levels) + { + // Find the ancestor of a dimension located a specified number of levels up. + // If such an ancestor does not exist, return the root dimension. + return null; + } } \ No newline at end of file diff --git a/src/main/resources/schematics/ruins/rules.txt b/src/main/resources/schematics/ruins/rules.txt index a14fe17..0618858 100644 --- a/src/main/resources/schematics/ruins/rules.txt +++ b/src/main/resources/schematics/ruins/rules.txt @@ -16,6 +16,8 @@ DistortDoorCoordinates = true ## Prevent this pack from being selected for transitioning in once we've transitioned out AllowPackChangeIn = false +DuplicateSearchLevels = 1 + Rules: Exit -> DeadEnd Exit