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.
This commit is contained in:
@@ -21,6 +21,7 @@ public class DungeonPack
|
|||||||
//FIXME: Do not release this code as an update without dealing with disowned types!
|
//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_HISTORY_LENGTH = 30;
|
||||||
|
private static final int MAX_SUBTREE_LIST_SIZE = 30;
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final HashMap<String, DungeonType> nameToTypeMapping;
|
private final HashMap<String, DungeonType> nameToTypeMapping;
|
||||||
@@ -136,15 +137,30 @@ public class DungeonPack
|
|||||||
|
|
||||||
int maxSearchLength = config.allowDuplicatesInChain() ? maxRuleLength : MAX_HISTORY_LENGTH;
|
int maxSearchLength = config.allowDuplicatesInChain() ? maxRuleLength : MAX_HISTORY_LENGTH;
|
||||||
ArrayList<DungeonData> history = DungeonHelper.getDungeonChainHistory(dimension, this, maxSearchLength);
|
ArrayList<DungeonData> history = DungeonHelper.getDungeonChainHistory(dimension, this, maxSearchLength);
|
||||||
return getNextDungeon(history, random);
|
|
||||||
|
ArrayList<DungeonData> subtreeHistory;
|
||||||
|
/*if (config.getDuplicateSearchLevels() > 0)
|
||||||
|
{
|
||||||
|
subtreeHistory = DungeonHelper.getFlatDungeonTree(
|
||||||
|
DungeonHelper.getAncestor(dimension, config.getDuplicateSearchLevels()),
|
||||||
|
MAX_SUBTREE_LIST_SIZE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
subtreeHistory = new ArrayList<DungeonData>();
|
||||||
|
}*/
|
||||||
|
subtreeHistory = new ArrayList<DungeonData>();
|
||||||
|
|
||||||
|
return getNextDungeon(history, subtreeHistory, random);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DungeonData getNextDungeon(ArrayList<DungeonData> history, Random random)
|
private DungeonData getNextDungeon(ArrayList<DungeonData> history, ArrayList<DungeonData> subtreeHistory, Random random)
|
||||||
{
|
{
|
||||||
//Extract the dungeon types that have been used from history and convert them into an array of IDs
|
//Extract the dungeon types that have been used from history and convert them into an array of IDs
|
||||||
int index;
|
int index;
|
||||||
int[] typeHistory = new int[history.size()];
|
int[] typeHistory = new int[history.size()];
|
||||||
HashSet<DungeonData> excludedDungeons = null;
|
HashSet<DungeonData> excludedDungeons = null;
|
||||||
|
boolean doExclude = !config.allowDuplicatesInChain() || !subtreeHistory.isEmpty();
|
||||||
for (index = 0; index < typeHistory.length; index++)
|
for (index = 0; index < typeHistory.length; index++)
|
||||||
{
|
{
|
||||||
typeHistory[index] = history.get(index).dungeonType().ID;
|
typeHistory[index] = history.get(index).dungeonType().ID;
|
||||||
@@ -163,9 +179,19 @@ public class DungeonPack
|
|||||||
if (nextType != null)
|
if (nextType != null)
|
||||||
{
|
{
|
||||||
//Initialize the set of excluded dungeons if needed
|
//Initialize the set of excluded dungeons if needed
|
||||||
if (excludedDungeons == null && !config.allowDuplicatesInChain())
|
if (excludedDungeons == null && doExclude)
|
||||||
{
|
{
|
||||||
excludedDungeons = new HashSet<DungeonData>(history);
|
if (config.allowDuplicatesInChain())
|
||||||
|
{
|
||||||
|
excludedDungeons = new HashSet<DungeonData>(subtreeHistory);
|
||||||
|
excludedDungeons.addAll(subtreeHistory);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
excludedDungeons = new HashSet<DungeonData>(2 * (history.size() + subtreeHistory.size()));
|
||||||
|
excludedDungeons.addAll(history);
|
||||||
|
excludedDungeons.addAll(subtreeHistory);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//List which dungeons are allowed
|
//List which dungeons are allowed
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ public class DungeonPackConfig
|
|||||||
private boolean allowPackChangeOut;
|
private boolean allowPackChangeOut;
|
||||||
private boolean distortDoorCoordinates;
|
private boolean distortDoorCoordinates;
|
||||||
private int packWeight;
|
private int packWeight;
|
||||||
|
private int duplicateSearchLevels;
|
||||||
private ArrayList<DungeonChainRuleDefinition> rules;
|
private ArrayList<DungeonChainRuleDefinition> rules;
|
||||||
|
|
||||||
public DungeonPackConfig() { }
|
public DungeonPackConfig() { }
|
||||||
@@ -25,6 +26,7 @@ public class DungeonPackConfig
|
|||||||
this.allowPackChangeOut = source.allowPackChangeOut;
|
this.allowPackChangeOut = source.allowPackChangeOut;
|
||||||
this.distortDoorCoordinates = source.distortDoorCoordinates;
|
this.distortDoorCoordinates = source.distortDoorCoordinates;
|
||||||
this.packWeight = source.packWeight;
|
this.packWeight = source.packWeight;
|
||||||
|
this.duplicateSearchLevels = source.duplicateSearchLevels;
|
||||||
this.rules = (source.rules != null) ? (ArrayList<DungeonChainRuleDefinition>) source.rules.clone() : null;
|
this.rules = (source.rules != null) ? (ArrayList<DungeonChainRuleDefinition>) source.rules.clone() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,6 +116,16 @@ public class DungeonPackConfig
|
|||||||
this.packWeight = packWeight;
|
this.packWeight = packWeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getDuplicateSearchLevels()
|
||||||
|
{
|
||||||
|
return duplicateSearchLevels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDuplicateSearchLevels(int duplicateSearchLevels)
|
||||||
|
{
|
||||||
|
this.duplicateSearchLevels = duplicateSearchLevels;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean doDistortDoorCoordinates()
|
public boolean doDistortDoorCoordinates()
|
||||||
{
|
{
|
||||||
return distortDoorCoordinates;
|
return distortDoorCoordinates;
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ public class DungeonPackConfigReader extends BaseConfigurationProcessor<DungeonP
|
|||||||
private final int DEFAULT_PRODUCT_WEIGHT = 100;
|
private final int DEFAULT_PRODUCT_WEIGHT = 100;
|
||||||
private final int MAX_DUNGEON_PACK_WEIGHT = 10000;
|
private final int MAX_DUNGEON_PACK_WEIGHT = 10000;
|
||||||
private final int MIN_DUNGEON_PACK_WEIGHT = 1;
|
private final int MIN_DUNGEON_PACK_WEIGHT = 1;
|
||||||
|
private final int MAX_DUPLICATE_SEARCH_LEVELS = 5;
|
||||||
|
private final int MIN_DUPLICATE_SEARCH_LEVELS = 0;
|
||||||
private final int DEFAULT_DUNGEON_PACK_WEIGHT = 100;
|
private final int DEFAULT_DUNGEON_PACK_WEIGHT = 100;
|
||||||
private final int MAX_CONDITION_LENGTH = 20;
|
private final int MAX_CONDITION_LENGTH = 20;
|
||||||
private final int MAX_PRODUCT_COUNT = MAX_CONDITION_LENGTH;
|
private final int MAX_PRODUCT_COUNT = MAX_CONDITION_LENGTH;
|
||||||
@@ -80,6 +82,7 @@ public class DungeonPackConfigReader extends BaseConfigurationProcessor<DungeonP
|
|||||||
config.setAllowPackChangeOut(true);
|
config.setAllowPackChangeOut(true);
|
||||||
config.setDistortDoorCoordinates(false);
|
config.setDistortDoorCoordinates(false);
|
||||||
config.setPackWeight(DEFAULT_DUNGEON_PACK_WEIGHT);
|
config.setPackWeight(DEFAULT_DUNGEON_PACK_WEIGHT);
|
||||||
|
config.setDuplicateSearchLevels(MIN_DUPLICATE_SEARCH_LEVELS);
|
||||||
|
|
||||||
//Read the settings section
|
//Read the settings section
|
||||||
if (findSection("Settings", reader))
|
if (findSection("Settings", reader))
|
||||||
@@ -273,6 +276,18 @@ public class DungeonPackConfigReader extends BaseConfigurationProcessor<DungeonP
|
|||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (name.equalsIgnoreCase("DuplicateSearchLevels"))
|
||||||
|
{
|
||||||
|
int levels = Integer.parseInt(value);
|
||||||
|
if (levels >= MIN_DUPLICATE_SEARCH_LEVELS && levels <= MAX_DUPLICATE_SEARCH_LEVELS)
|
||||||
|
{
|
||||||
|
config.setDuplicateSearchLevels(levels);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
valid = false;
|
valid = false;
|
||||||
|
|||||||
@@ -664,4 +664,11 @@ public class DungeonHelper
|
|||||||
}
|
}
|
||||||
return dungeons;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -16,6 +16,8 @@ DistortDoorCoordinates = true
|
|||||||
## Prevent this pack from being selected for transitioning in once we've transitioned out
|
## Prevent this pack from being selected for transitioning in once we've transitioned out
|
||||||
AllowPackChangeIn = false
|
AllowPackChangeIn = false
|
||||||
|
|
||||||
|
DuplicateSearchLevels = 1
|
||||||
|
|
||||||
Rules:
|
Rules:
|
||||||
|
|
||||||
Exit -> DeadEnd Exit
|
Exit -> DeadEnd Exit
|
||||||
|
|||||||
Reference in New Issue
Block a user