Progress on Implementing Dungeon Packs
Completed enough of the implementation and integration to compile DD. Some portions of the code are only for testing and will be removed later. The configuration for default dungeons is hardcoded - we can parse config files once we're certain that dungeon chains work. At the moment, dungeons generate but it doesn't seem like the rules we set are being followed properly. Renamed OptimizedRule to DungeonChainRule, and renamed the old DungeonChainRule to DungeonChainRuleDefinition, to match the role of each class better. Added some hax to DungeonGenerator to get packs integrated - the implementation will be much cleaner once the new save format is done.
This commit is contained in:
@@ -1,14 +1,22 @@
|
|||||||
package StevenDimDoors.mod_pocketDim;
|
package StevenDimDoors.mod_pocketDim;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonType;
|
||||||
|
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
|
||||||
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class DungeonGenerator implements Serializable
|
public class DungeonGenerator implements Serializable
|
||||||
{
|
{
|
||||||
|
//This static field is hax so that I don't have to add an instance field to DungeonGenerator to support DungeonType.
|
||||||
|
//Otherwise it would have to be serializable and all sorts of problems would arise.
|
||||||
|
private static final HashMap<DungeonGenerator, DungeonType> dungeonTypes = new HashMap<DungeonGenerator, DungeonType>();
|
||||||
|
|
||||||
public int weight;
|
public int weight;
|
||||||
public String schematicPath;
|
public String schematicPath;
|
||||||
public ArrayList<HashMap> sideRifts = new ArrayList<HashMap>();
|
public ArrayList<HashMap> sideRifts = new ArrayList<HashMap>();
|
||||||
@@ -19,10 +27,54 @@ public class DungeonGenerator implements Serializable
|
|||||||
public int exitDoorsSoFar=0;
|
public int exitDoorsSoFar=0;
|
||||||
public int deadEndsSoFar=0;
|
public int deadEndsSoFar=0;
|
||||||
|
|
||||||
public DungeonGenerator(int weight, String schematicPath, Boolean isOpen)
|
public DungeonGenerator(int weight, String schematicPath, boolean isOpen, DungeonType dungeonType)
|
||||||
{
|
{
|
||||||
this.weight=weight;
|
this.weight = weight;
|
||||||
this.schematicPath=schematicPath;
|
this.schematicPath = schematicPath;
|
||||||
this.isOpen=isOpen;
|
this.isOpen = isOpen;
|
||||||
|
|
||||||
|
dungeonTypes.put(this, dungeonType); //Hax...
|
||||||
|
}
|
||||||
|
|
||||||
|
public DungeonType getDungeonType()
|
||||||
|
{
|
||||||
|
DungeonType type = dungeonTypes.get(this);
|
||||||
|
if (type == null)
|
||||||
|
{
|
||||||
|
//Infer the dungeon's type from its file name
|
||||||
|
//There is minimal risk of us applying this to untagged dungeons and this'll be phased out
|
||||||
|
//when we get the new save format.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File file = new File(schematicPath);
|
||||||
|
String typeName = file.getName().split("_")[0];
|
||||||
|
type = DungeonHelper.instance().RuinsPack.getType(typeName);
|
||||||
|
}
|
||||||
|
catch (Exception e) { }
|
||||||
|
if (type == null)
|
||||||
|
{
|
||||||
|
type = DungeonType.UNKNOWN_TYPE;
|
||||||
|
}
|
||||||
|
dungeonTypes.put(this, type);
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return (schematicPath != null) ? schematicPath.hashCode() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other)
|
||||||
|
{
|
||||||
|
return equals((DungeonGenerator) other);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(DungeonGenerator other)
|
||||||
|
{
|
||||||
|
return ((this.schematicPath != null && this.schematicPath.equals(other.schematicPath)) ||
|
||||||
|
(this.schematicPath == other.schematicPath));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,6 +28,7 @@ public class SchematicLoader
|
|||||||
int originDimID = link.locDimID;
|
int originDimID = link.locDimID;
|
||||||
int destDimID = link.destDimID;
|
int destDimID = link.destDimID;
|
||||||
HashMap<Integer, DimData> dimList = dimHelper.dimList;
|
HashMap<Integer, DimData> dimList = dimHelper.dimList;
|
||||||
|
DungeonHelper dungeonHelper = DungeonHelper.instance();
|
||||||
World world;
|
World world;
|
||||||
|
|
||||||
if (dimList.containsKey(destDimID))
|
if (dimList.containsKey(destDimID))
|
||||||
@@ -49,8 +50,7 @@ public class SchematicLoader
|
|||||||
long factorB = random.nextLong() / 2L * 2L + 1L;
|
long factorB = random.nextLong() / 2L * 2L + 1L;
|
||||||
random.setSeed((link.destXCoord >> 4) * factorA + (link.destZCoord >> 4) * factorB ^ world.getSeed());
|
random.setSeed((link.destXCoord >> 4) * factorA + (link.destZCoord >> 4) * factorB ^ world.getSeed());
|
||||||
|
|
||||||
//TODO: FIX THIS LINE OR SADNESS WILL FOLLOW. Add a reference to the dungeon pack.
|
dungeonHelper.generateDungeonLink(link, dungeonHelper.RuinsPack, random);
|
||||||
//DungeonHelper.instance().generateDungeonLink(link, ???, random);
|
|
||||||
}
|
}
|
||||||
schematicPath = dimList.get(destDimID).dungeonGenerator.schematicPath;
|
schematicPath = dimList.get(destDimID).dungeonGenerator.schematicPath;
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ public class SchematicLoader
|
|||||||
//TODO: In the future, remove this dungeon from the generation lists altogether.
|
//TODO: In the future, remove this dungeon from the generation lists altogether.
|
||||||
//That will have to wait until our code is updated to support that more easily.
|
//That will have to wait until our code is updated to support that more easily.
|
||||||
System.err.println("The dungeon will not be loaded.");
|
System.err.println("The dungeon will not be loaded.");
|
||||||
DungeonGenerator defaultError = DungeonHelper.instance().getDefaultErrorDungeon();
|
DungeonGenerator defaultError = dungeonHelper.getDefaultErrorDungeon();
|
||||||
dimList.get(destDimID).dungeonGenerator = defaultError;
|
dimList.get(destDimID).dungeonGenerator = defaultError;
|
||||||
dungeon = checkSourceAndLoad(defaultError.schematicPath);
|
dungeon = checkSourceAndLoad(defaultError.schematicPath);
|
||||||
dungeon.applyImportFilters(properties);
|
dungeon.applyImportFilters(properties);
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class CommandExportDungeon extends DDCommandBase
|
|||||||
if (command[1].equalsIgnoreCase("override"))
|
if (command[1].equalsIgnoreCase("override"))
|
||||||
{
|
{
|
||||||
//Check that the schematic name is a legal name
|
//Check that the schematic name is a legal name
|
||||||
if (DungeonHelper.SchematicNamePattern.matcher(command[0]).matches())
|
if (DungeonHelper.SCHEMATIC_NAME_PATTERN.matcher(command[0]).matches())
|
||||||
{
|
{
|
||||||
//Export the schematic
|
//Export the schematic
|
||||||
return exportDungeon(sender, command[0]);
|
return exportDungeon(sender, command[0]);
|
||||||
@@ -85,7 +85,7 @@ public class CommandExportDungeon extends DDCommandBase
|
|||||||
{
|
{
|
||||||
return new DDCommandResult("Error: Invalid dungeon type. Please use one of the existing types.");
|
return new DDCommandResult("Error: Invalid dungeon type. Please use one of the existing types.");
|
||||||
}
|
}
|
||||||
if (!DungeonHelper.DungeonNamePattern.matcher(command[1]).matches())
|
if (!DungeonHelper.DUNGEON_NAME_PATTERN.matcher(command[1]).matches())
|
||||||
{
|
{
|
||||||
return new DDCommandResult("Error: Invalid dungeon name. Please use only letters, numbers, and dashes.");
|
return new DDCommandResult("Error: Invalid dungeon name. Please use only letters, numbers, and dashes.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,66 @@
|
|||||||
package StevenDimDoors.mod_pocketDim.dungeon.pack;
|
package StevenDimDoors.mod_pocketDim.dungeon.pack;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import StevenDimDoors.mod_pocketDim.util.WeightedContainer;
|
||||||
|
|
||||||
public class DungeonChainRule
|
public class DungeonChainRule
|
||||||
{
|
{
|
||||||
|
private final int[] condition;
|
||||||
|
private final ArrayList<WeightedContainer<DungeonType>> products;
|
||||||
|
|
||||||
public OptimizedRule optimize(HashMap<String, DungeonType> nameToTypeMapping) {
|
public DungeonChainRule(DungeonChainRuleDefinition source, HashMap<String, DungeonType> nameToTypeMapping)
|
||||||
// TODO Auto-generated method stub
|
{
|
||||||
return null;
|
ArrayList<String> conditionNames = source.getCondition();
|
||||||
|
ArrayList<WeightedContainer<String>> productNames = source.getProducts();
|
||||||
|
|
||||||
|
condition = new int[conditionNames.size()];
|
||||||
|
for (int k = 0; k < condition.length; k++)
|
||||||
|
{
|
||||||
|
condition[k] = nameToTypeMapping.get(conditionNames.get(k)).ID;
|
||||||
|
}
|
||||||
|
products = new ArrayList<WeightedContainer<DungeonType>>();
|
||||||
|
for (WeightedContainer<String> product : productNames)
|
||||||
|
{
|
||||||
|
products.add(new WeightedContainer<DungeonType>(nameToTypeMapping.get(product.getData()), product.itemWeight ));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int length()
|
||||||
|
{
|
||||||
|
return condition.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean evaluate(int[] typeHistory)
|
||||||
|
{
|
||||||
|
if (typeHistory.length >= condition.length)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < condition.length; k++)
|
||||||
|
{
|
||||||
|
if (condition[k] != 0 && typeHistory[k] != condition[k])
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<WeightedContainer<DungeonType>> products()
|
||||||
|
{
|
||||||
|
//Create a deep copy of the internal list of products. That way, if the list is modified externally,
|
||||||
|
//it won't affect the reference copy inside this rule.
|
||||||
|
ArrayList<WeightedContainer<DungeonType>> copy = new ArrayList<WeightedContainer<DungeonType>>(products.size());
|
||||||
|
for (WeightedContainer<DungeonType> container : products)
|
||||||
|
{
|
||||||
|
copy.add(container.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import net.minecraft.util.WeightedRandom;
|
import net.minecraft.util.WeightedRandom;
|
||||||
@@ -16,9 +15,11 @@ import StevenDimDoors.mod_pocketDim.util.WeightedContainer;
|
|||||||
|
|
||||||
public class DungeonPack
|
public class DungeonPack
|
||||||
{
|
{
|
||||||
//Why final? I just felt like it, honestly. ~SenseiKiwi
|
//There is no precaution against having a dungeon type removed from a config file after dungeons of that type
|
||||||
|
//have been generated. That would likely cause one or two problems. It's hard to guard against when I don't know
|
||||||
private static final DungeonType WILDCARD_TYPE = new DungeonType(null, "?", 0);
|
//what the save format will be like completely. How should this class behave if it finds a "disowned" type?
|
||||||
|
//The ID numbers would be a problem since it couldn't have a valid number, since it wasn't initialized by the pack instance.
|
||||||
|
//FIXME: Do not release this code as an update without dealing with disowned types!
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final HashMap<String, DungeonType> nameToTypeMapping;
|
private final HashMap<String, DungeonType> nameToTypeMapping;
|
||||||
@@ -26,7 +27,7 @@ public class DungeonPack
|
|||||||
private final ArrayList<DungeonGenerator> allDungeons;
|
private final ArrayList<DungeonGenerator> allDungeons;
|
||||||
private final DungeonPackConfig config;
|
private final DungeonPackConfig config;
|
||||||
private final int maxRuleLength;
|
private final int maxRuleLength;
|
||||||
private final ArrayList<OptimizedRule> rules;
|
private final ArrayList<DungeonChainRule> rules;
|
||||||
|
|
||||||
public DungeonPack(DungeonPackConfig config)
|
public DungeonPack(DungeonPackConfig config)
|
||||||
{
|
{
|
||||||
@@ -42,7 +43,7 @@ public class DungeonPack
|
|||||||
this.groupedDungeons = new ArrayList<ArrayList<DungeonGenerator>>(typeCount);
|
this.groupedDungeons = new ArrayList<ArrayList<DungeonGenerator>>(typeCount);
|
||||||
|
|
||||||
this.groupedDungeons.add(allDungeons); //Make sure the list of all dungeons is placed at index 0
|
this.groupedDungeons.add(allDungeons); //Make sure the list of all dungeons is placed at index 0
|
||||||
this.nameToTypeMapping.put(WILDCARD_TYPE.Name, WILDCARD_TYPE);
|
this.nameToTypeMapping.put(DungeonType.WILDCARD_TYPE.Name, DungeonType.WILDCARD_TYPE);
|
||||||
|
|
||||||
index = 1;
|
index = 1;
|
||||||
for (String typeName : config.getTypeNames())
|
for (String typeName : config.getTypeNames())
|
||||||
@@ -53,22 +54,23 @@ public class DungeonPack
|
|||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Construct optimized rules from config rules
|
//Construct optimized rules from definitions
|
||||||
ArrayList<DungeonChainRule> chainRules = config.getRules();
|
ArrayList<DungeonChainRuleDefinition> definitions = config.getRules();
|
||||||
this.rules = new ArrayList<OptimizedRule>(chainRules.size());
|
this.rules = new ArrayList<DungeonChainRule>(definitions.size());
|
||||||
for (DungeonChainRule rule : chainRules)
|
for (DungeonChainRuleDefinition definition : definitions)
|
||||||
{
|
{
|
||||||
OptimizedRule optimized = rule.optimize(nameToTypeMapping);
|
DungeonChainRule rule = new DungeonChainRule(definition, nameToTypeMapping);
|
||||||
this.rules.add(optimized);
|
this.rules.add(rule);
|
||||||
if (maxLength < optimized.length())
|
if (maxLength < rule.length())
|
||||||
{
|
{
|
||||||
maxLength = optimized.length();
|
maxLength = rule.length();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.maxRuleLength = maxLength;
|
this.maxRuleLength = maxLength;
|
||||||
|
|
||||||
//Remove the reference to the non-optimized rules to free up memory - we won't need them here
|
//Remove unnecessary references to save a little memory - we won't need them here
|
||||||
this.config.setRules(null);
|
this.config.setRules(null);
|
||||||
|
this.config.setTypeNames(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName()
|
public String getName()
|
||||||
@@ -84,7 +86,7 @@ public class DungeonPack
|
|||||||
public DungeonType getType(String typeName)
|
public DungeonType getType(String typeName)
|
||||||
{
|
{
|
||||||
DungeonType result = nameToTypeMapping.get(typeName.toUpperCase());
|
DungeonType result = nameToTypeMapping.get(typeName.toUpperCase());
|
||||||
if (result != WILDCARD_TYPE)
|
if (result.Owner == this) //Filter out the wildcard dungeon type
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -99,6 +101,21 @@ public class DungeonPack
|
|||||||
return (this.getType(typeName) != null);
|
return (this.getType(typeName) != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addDungeon(DungeonGenerator generator)
|
||||||
|
{
|
||||||
|
//Make sure this dungeon really belongs in this pack
|
||||||
|
DungeonType type = generator.getDungeonType();
|
||||||
|
if (type.Owner == this)
|
||||||
|
{
|
||||||
|
allDungeons.add(generator);
|
||||||
|
groupedDungeons.get(type.ID).add(generator);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("The dungeon type of generator must belong to this instance of DungeonPack.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public DungeonGenerator getNextDungeon(LinkData inbound, Random random)
|
public DungeonGenerator getNextDungeon(LinkData inbound, Random random)
|
||||||
{
|
{
|
||||||
if (allDungeons.isEmpty())
|
if (allDungeons.isEmpty())
|
||||||
@@ -106,12 +123,14 @@ public class DungeonPack
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Retrieve a list of the previous dungeons in this chain. Restrict the length of the
|
//Retrieve a list of the previous dungeons in this chain.
|
||||||
//search to the length of the longest rule. Getting more data is useless.
|
//If we're not going to check for duplicates in chains, restrict the length of the history to the length
|
||||||
dimHelper helper = dimHelper.instance;
|
//of the longest rule we have. Getting any more data would be useless. This optimization could be significant
|
||||||
|
//for dungeon packs that can extend arbitrarily deep. We should probably set a reasonable limit anyway.
|
||||||
|
|
||||||
//TODO: Add dungeon pack parameter! We can't use dungeon types from other packs.
|
int maxSearchLength = config.allowDuplicatesInChain() ? maxRuleLength : 1337;
|
||||||
ArrayList<DungeonGenerator> history = DungeonHelper.getDungeonChainHistory(helper.getDimData(inbound.locDimID), maxRuleLength);
|
ArrayList<DungeonGenerator> history = DungeonHelper.getDungeonChainHistory(
|
||||||
|
dimHelper.instance.getDimData(inbound.locDimID), this, maxSearchLength);
|
||||||
return getNextDungeon(history, random);
|
return getNextDungeon(history, random);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,10 +142,10 @@ public class DungeonPack
|
|||||||
HashSet<DungeonGenerator> excludedDungeons = null;
|
HashSet<DungeonGenerator> excludedDungeons = null;
|
||||||
for (index = 0; index < typeHistory.length; index++)
|
for (index = 0; index < typeHistory.length; index++)
|
||||||
{
|
{
|
||||||
typeHistory[index] = getDungeonType(history.get(index)).ID;
|
typeHistory[index] = history.get(index).getDungeonType().ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (OptimizedRule rule : rules)
|
for (DungeonChainRule rule : rules)
|
||||||
{
|
{
|
||||||
if (rule.evaluate(typeHistory))
|
if (rule.evaluate(typeHistory))
|
||||||
{
|
{
|
||||||
@@ -139,9 +158,9 @@ 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 && !config.allowDuplicatesInChain())
|
||||||
{
|
{
|
||||||
//TODO: Finish implementing this!
|
excludedDungeons = new HashSet<DungeonGenerator>(history);
|
||||||
}
|
}
|
||||||
|
|
||||||
//List which dungeons are allowed
|
//List which dungeons are allowed
|
||||||
@@ -166,6 +185,8 @@ public class DungeonPack
|
|||||||
{
|
{
|
||||||
return getRandomDungeon(random, candidates);
|
return getRandomDungeon(random, candidates);
|
||||||
}
|
}
|
||||||
|
//If we've reached this point, then a dungeon was not selected. Discard the type and try again.
|
||||||
|
products.remove(nextType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (nextType != null);
|
while (nextType != null);
|
||||||
@@ -176,16 +197,6 @@ public class DungeonPack
|
|||||||
return getRandomDungeon(random);
|
return getRandomDungeon(random);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DungeonType getDungeonType(DungeonGenerator generator)
|
|
||||||
{
|
|
||||||
//This function is a workaround for DungeonGenerator not having a dungeon type or pack field.
|
|
||||||
//I really don't want to go messing around with that serializable type.
|
|
||||||
//TODO: Remove this function once we transition to using the new save format. ~SenseiKiwi
|
|
||||||
|
|
||||||
//TODO: Finish implementing this!
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DungeonGenerator getRandomDungeon(Random random)
|
public DungeonGenerator getRandomDungeon(Random random)
|
||||||
{
|
{
|
||||||
if (!allDungeons.isEmpty())
|
if (!allDungeons.isEmpty())
|
||||||
@@ -202,7 +213,7 @@ public class DungeonPack
|
|||||||
ArrayList<ArrayList<DungeonGenerator>> groupedDungeons)
|
ArrayList<ArrayList<DungeonGenerator>> groupedDungeons)
|
||||||
{
|
{
|
||||||
//TODO: Make this faster? This algorithm runs in quadratic time in the worst case because of the random-selection
|
//TODO: Make this faster? This algorithm runs in quadratic time in the worst case because of the random-selection
|
||||||
//process and the removal search. Should be okay for normal use, though. ~SenseiKiwi
|
//process and the removal search. Might be okay for normal use, though. ~SenseiKiwi
|
||||||
|
|
||||||
//Pick a random dungeon type based on weights. Repeat this process until a non-empty group is found or all groups are checked.
|
//Pick a random dungeon type based on weights. Repeat this process until a non-empty group is found or all groups are checked.
|
||||||
while (!types.isEmpty())
|
while (!types.isEmpty())
|
||||||
|
|||||||
@@ -1,22 +1,36 @@
|
|||||||
package StevenDimDoors.mod_pocketDim.dungeon.pack;
|
package StevenDimDoors.mod_pocketDim.dungeon.pack;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class DungeonPackConfig
|
public class DungeonPackConfig
|
||||||
{
|
{
|
||||||
|
private String name;
|
||||||
|
private ArrayList<String> typeNames;
|
||||||
|
private boolean allowDuplicatesInChain;
|
||||||
|
private ArrayList<DungeonChainRuleDefinition> rules;
|
||||||
|
|
||||||
public DungeonPackConfig() { }
|
public DungeonPackConfig() { }
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
private DungeonPackConfig(DungeonPackConfig source)
|
private DungeonPackConfig(DungeonPackConfig source)
|
||||||
{
|
{
|
||||||
|
this.name = source.name;
|
||||||
|
this.typeNames = (ArrayList<String>) source.typeNames.clone();
|
||||||
|
this.allowDuplicatesInChain = source.allowDuplicatesInChain;
|
||||||
|
this.rules = (ArrayList<DungeonChainRuleDefinition>) source.rules.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validate()
|
public void validate()
|
||||||
{
|
{
|
||||||
|
if (this.name == null)
|
||||||
|
throw new NullPointerException("name cannot be null");
|
||||||
|
if (this.typeNames == null)
|
||||||
|
throw new NullPointerException("typeNames cannot be null");
|
||||||
|
if (this.rules == null)
|
||||||
|
throw new NullPointerException("rules cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public DungeonPackConfig clone()
|
public DungeonPackConfig clone()
|
||||||
{
|
{
|
||||||
return new DungeonPackConfig(this);
|
return new DungeonPackConfig(this);
|
||||||
@@ -24,26 +38,41 @@ public class DungeonPackConfig
|
|||||||
|
|
||||||
public String getName()
|
public String getName()
|
||||||
{
|
{
|
||||||
return null;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getTypeNames()
|
public void setName(String name)
|
||||||
{
|
{
|
||||||
return null;
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<String> getTypeNames()
|
||||||
|
{
|
||||||
|
return typeNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTypeNames(ArrayList<String> typeNames)
|
||||||
|
{
|
||||||
|
this.typeNames = typeNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean allowDuplicatesInChain()
|
public boolean allowDuplicatesInChain()
|
||||||
{
|
{
|
||||||
return false;
|
return allowDuplicatesInChain;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRules(Object object) {
|
public void setAllowDuplicatesInChain(boolean value)
|
||||||
// TODO Auto-generated method stub
|
{
|
||||||
|
allowDuplicatesInChain = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<DungeonChainRule> getRules() {
|
public void setRules(ArrayList<DungeonChainRuleDefinition> rules)
|
||||||
// TODO Auto-generated method stub
|
{
|
||||||
return null;
|
this.rules = rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<DungeonChainRuleDefinition> getRules()
|
||||||
|
{
|
||||||
|
return rules;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ package StevenDimDoors.mod_pocketDim.dungeon.pack;
|
|||||||
|
|
||||||
public class DungeonType implements Comparable<DungeonType>
|
public class DungeonType implements Comparable<DungeonType>
|
||||||
{
|
{
|
||||||
|
public static final DungeonType WILDCARD_TYPE = new DungeonType(null, "?", 0);
|
||||||
|
public static final DungeonType UNKNOWN_TYPE = new DungeonType(null, "!", -1);
|
||||||
|
|
||||||
public final DungeonPack Owner;
|
public final DungeonPack Owner;
|
||||||
public final String Name;
|
public final String Name;
|
||||||
public final int ID;
|
public final int ID;
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
package StevenDimDoors.mod_pocketDim.dungeon.pack;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import StevenDimDoors.mod_pocketDim.util.WeightedContainer;
|
|
||||||
|
|
||||||
public class OptimizedRule
|
|
||||||
{
|
|
||||||
|
|
||||||
public int length() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean evaluate(int[] typeHistory) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ArrayList<WeightedContainer<DungeonType>> products() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -5,9 +5,9 @@ import java.io.File;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@@ -20,15 +20,20 @@ import StevenDimDoors.mod_pocketDim.DungeonGenerator;
|
|||||||
import StevenDimDoors.mod_pocketDim.LinkData;
|
import StevenDimDoors.mod_pocketDim.LinkData;
|
||||||
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
|
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
|
||||||
import StevenDimDoors.mod_pocketDim.dungeon.DungeonSchematic;
|
import StevenDimDoors.mod_pocketDim.dungeon.DungeonSchematic;
|
||||||
|
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonChainRuleDefinition;
|
||||||
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPack;
|
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPack;
|
||||||
|
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPackConfig;
|
||||||
|
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonType;
|
||||||
import StevenDimDoors.mod_pocketDim.items.itemDimDoor;
|
import StevenDimDoors.mod_pocketDim.items.itemDimDoor;
|
||||||
|
import StevenDimDoors.mod_pocketDim.util.WeightedContainer;
|
||||||
|
|
||||||
public class DungeonHelper
|
public class DungeonHelper
|
||||||
{
|
{
|
||||||
private static DungeonHelper instance = null;
|
private static DungeonHelper instance = null;
|
||||||
private static DDProperties properties = null;
|
private static DDProperties properties = null;
|
||||||
public static final Pattern SchematicNamePattern = Pattern.compile("[A-Za-z0-9_\\-]+");
|
|
||||||
public static final Pattern DungeonNamePattern = Pattern.compile("[A-Za-z0-9\\-]+");
|
public static final Pattern SCHEMATIC_NAME_PATTERN = Pattern.compile("[A-Za-z0-9_\\-]+");
|
||||||
|
public static final Pattern DUNGEON_NAME_PATTERN = Pattern.compile("[A-Za-z0-9\\-]+");
|
||||||
|
|
||||||
private static final String DEFAULT_UP_SCHEMATIC_PATH = "/schematics/core/simpleStairsUp.schematic";
|
private static final String DEFAULT_UP_SCHEMATIC_PATH = "/schematics/core/simpleStairsUp.schematic";
|
||||||
private static final String DEFAULT_DOWN_SCHEMATIC_PATH = "/schematics/core/simpleStairsDown.schematic";
|
private static final String DEFAULT_DOWN_SCHEMATIC_PATH = "/schematics/core/simpleStairsDown.schematic";
|
||||||
@@ -44,70 +49,22 @@ public class DungeonHelper
|
|||||||
public static final short MAX_DUNGEON_HEIGHT = MAX_DUNGEON_WIDTH;
|
public static final short MAX_DUNGEON_HEIGHT = MAX_DUNGEON_WIDTH;
|
||||||
public static final short MAX_DUNGEON_LENGTH = MAX_DUNGEON_WIDTH;
|
public static final short MAX_DUNGEON_LENGTH = MAX_DUNGEON_WIDTH;
|
||||||
|
|
||||||
private static final String HUB_DUNGEON_TYPE = "Hub";
|
|
||||||
private static final String TRAP_DUNGEON_TYPE = "Trap";
|
|
||||||
private static final String SIMPLE_HALL_DUNGEON_TYPE = "SimpleHall";
|
|
||||||
private static final String COMPLEX_HALL_DUNGEON_TYPE = "ComplexHall";
|
|
||||||
private static final String EXIT_DUNGEON_TYPE = "Exit";
|
|
||||||
private static final String DEAD_END_DUNGEON_TYPE = "DeadEnd";
|
|
||||||
private static final String MAZE_DUNGEON_TYPE = "Maze";
|
|
||||||
|
|
||||||
//The list of dungeon types will be kept as an array for now. If we allow new
|
|
||||||
//dungeon types in the future, then this can be changed to an ArrayList.
|
|
||||||
private static final String[] DUNGEON_TYPES = new String[] {
|
|
||||||
HUB_DUNGEON_TYPE,
|
|
||||||
TRAP_DUNGEON_TYPE,
|
|
||||||
SIMPLE_HALL_DUNGEON_TYPE,
|
|
||||||
COMPLEX_HALL_DUNGEON_TYPE,
|
|
||||||
EXIT_DUNGEON_TYPE,
|
|
||||||
DEAD_END_DUNGEON_TYPE,
|
|
||||||
MAZE_DUNGEON_TYPE
|
|
||||||
};
|
|
||||||
|
|
||||||
private ArrayList<DungeonGenerator> untaggedDungeons = new ArrayList<DungeonGenerator>();
|
private ArrayList<DungeonGenerator> untaggedDungeons = new ArrayList<DungeonGenerator>();
|
||||||
private ArrayList<DungeonGenerator> registeredDungeons = new ArrayList<DungeonGenerator>();
|
private ArrayList<DungeonGenerator> registeredDungeons = new ArrayList<DungeonGenerator>();
|
||||||
|
|
||||||
private ArrayList<DungeonGenerator> simpleHalls = new ArrayList<DungeonGenerator>();
|
public DungeonPack RuinsPack;
|
||||||
private ArrayList<DungeonGenerator> complexHalls = new ArrayList<DungeonGenerator>();
|
|
||||||
private ArrayList<DungeonGenerator> deadEnds = new ArrayList<DungeonGenerator>();
|
|
||||||
private ArrayList<DungeonGenerator> hubs = new ArrayList<DungeonGenerator>();
|
|
||||||
private ArrayList<DungeonGenerator> mazes = new ArrayList<DungeonGenerator>();
|
|
||||||
private ArrayList<DungeonGenerator> pistonTraps = new ArrayList<DungeonGenerator>();
|
|
||||||
private ArrayList<DungeonGenerator> exits = new ArrayList<DungeonGenerator>();
|
|
||||||
|
|
||||||
private DungeonGenerator defaultUp;
|
private DungeonGenerator defaultUp;
|
||||||
private DungeonGenerator defaultDown;
|
private DungeonGenerator defaultDown;
|
||||||
private DungeonGenerator defaultError;
|
private DungeonGenerator defaultError;
|
||||||
|
|
||||||
private HashSet<String> dungeonTypeChecker;
|
|
||||||
private HashMap<String, ArrayList<DungeonGenerator>> dungeonTypeMapping;
|
|
||||||
|
|
||||||
private DungeonHelper()
|
private DungeonHelper()
|
||||||
{
|
{
|
||||||
//Load the dungeon type checker with the list of all types in lowercase.
|
|
||||||
//Capitalization matters for matching in a hash set.
|
|
||||||
dungeonTypeChecker = new HashSet<String>();
|
|
||||||
for (String dungeonType : DUNGEON_TYPES)
|
|
||||||
{
|
|
||||||
dungeonTypeChecker.add(dungeonType.toLowerCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
//Add all the basic dungeon types to dungeonTypeMapping
|
|
||||||
//Dungeon type names must be passed in lowercase to make matching easier.
|
|
||||||
dungeonTypeMapping = new HashMap<String, ArrayList<DungeonGenerator>>();
|
|
||||||
dungeonTypeMapping.put(SIMPLE_HALL_DUNGEON_TYPE.toLowerCase(), simpleHalls);
|
|
||||||
dungeonTypeMapping.put(COMPLEX_HALL_DUNGEON_TYPE.toLowerCase(), complexHalls);
|
|
||||||
dungeonTypeMapping.put(HUB_DUNGEON_TYPE.toLowerCase(), hubs);
|
|
||||||
dungeonTypeMapping.put(EXIT_DUNGEON_TYPE.toLowerCase(), exits);
|
|
||||||
dungeonTypeMapping.put(DEAD_END_DUNGEON_TYPE.toLowerCase(), deadEnds);
|
|
||||||
dungeonTypeMapping.put(MAZE_DUNGEON_TYPE.toLowerCase(), mazes);
|
|
||||||
dungeonTypeMapping.put(TRAP_DUNGEON_TYPE.toLowerCase(), pistonTraps);
|
|
||||||
|
|
||||||
//Load our reference to the DDProperties singleton
|
//Load our reference to the DDProperties singleton
|
||||||
if (properties == null)
|
if (properties == null)
|
||||||
properties = DDProperties.instance();
|
properties = DDProperties.instance();
|
||||||
|
|
||||||
registerCustomDungeons();
|
registerDungeons();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DungeonHelper initialize()
|
public static DungeonHelper initialize()
|
||||||
@@ -135,15 +92,67 @@ public class DungeonHelper
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerCustomDungeons()
|
private void registerDungeons()
|
||||||
{
|
{
|
||||||
File file = new File(properties.CustomSchematicDirectory);
|
File file = new File(properties.CustomSchematicDirectory);
|
||||||
if (file.exists() || file.mkdir())
|
if (file.exists() || file.mkdir())
|
||||||
{
|
{
|
||||||
copyfile.copyFile(DUNGEON_CREATION_GUIDE_SOURCE_PATH, file.getAbsolutePath() + "/How_to_add_dungeons.txt");
|
copyfile.copyFile(DUNGEON_CREATION_GUIDE_SOURCE_PATH, file.getAbsolutePath() + "/How_to_add_dungeons.txt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RuinsPack = new DungeonPack(createRuinsConfig());
|
||||||
|
|
||||||
registerBundledDungeons();
|
registerBundledDungeons();
|
||||||
importCustomDungeons(properties.CustomSchematicDirectory);
|
registerCustomDungeons(properties.CustomSchematicDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DungeonPackConfig createRuinsConfig()
|
||||||
|
{
|
||||||
|
//This is a temporarily function for testing dungeon packs.
|
||||||
|
//It'll be removed later when we read dungeon configurations from files.
|
||||||
|
|
||||||
|
ArrayList<DungeonChainRuleDefinition> rules = new ArrayList<DungeonChainRuleDefinition>();
|
||||||
|
rules.add(parseDefinitionUnsafe("? ? ? -> DeadEnd Exit"));
|
||||||
|
rules.add(parseDefinitionUnsafe("Trap -> ?"));
|
||||||
|
rules.add(parseDefinitionUnsafe("Hub -> Trap"));
|
||||||
|
rules.add(parseDefinitionUnsafe("? -> Hub"));
|
||||||
|
rules.add(parseDefinitionUnsafe("-> ComplexHall#40 Hub#30 Trap#10 SimpleHall#10 Maze#10"));
|
||||||
|
|
||||||
|
String[] typeNames = "Hub Trap Maze Exit DeadEnd SimpleHall ComplexHall".toUpperCase().split(" ");
|
||||||
|
|
||||||
|
DungeonPackConfig config = new DungeonPackConfig();
|
||||||
|
config.setName("ruins");
|
||||||
|
config.setAllowDuplicatesInChain(false);
|
||||||
|
config.setRules(rules);
|
||||||
|
config.setTypeNames(new ArrayList<String>(Arrays.asList(typeNames)));
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DungeonChainRuleDefinition parseDefinitionUnsafe(String definition)
|
||||||
|
{
|
||||||
|
//This is an improvised parsing function for rule definitions. Only for testing!!!
|
||||||
|
definition = definition.toUpperCase();
|
||||||
|
String[] parts = definition.split("->");
|
||||||
|
ArrayList<String> condition = new ArrayList<String>();
|
||||||
|
ArrayList<WeightedContainer<String>> products = new ArrayList<WeightedContainer<String>>();
|
||||||
|
|
||||||
|
for (String conditionPart : parts[0].split(" "))
|
||||||
|
{
|
||||||
|
if (!conditionPart.isEmpty())
|
||||||
|
condition.add(conditionPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String product : parts[1].split(" "))
|
||||||
|
{
|
||||||
|
if (!product.isEmpty())
|
||||||
|
{
|
||||||
|
String[] productParts = product.split("#");
|
||||||
|
String productType = productParts[0];
|
||||||
|
int weight = (productParts.length > 1) ? Integer.parseInt(productParts[1]) : 100;
|
||||||
|
products.add(new WeightedContainer<String>(productType, weight));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new DungeonChainRuleDefinition(condition, products);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DungeonGenerator> getRegisteredDungeons()
|
public List<DungeonGenerator> getRegisteredDungeons()
|
||||||
@@ -186,7 +195,7 @@ public class DungeonHelper
|
|||||||
public boolean validateDungeonType(String type)
|
public boolean validateDungeonType(String type)
|
||||||
{
|
{
|
||||||
//Check if the dungeon type is valid
|
//Check if the dungeon type is valid
|
||||||
return dungeonTypeChecker.contains(type.toLowerCase());
|
return RuinsPack.isKnownType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean validateSchematicName(String name)
|
public boolean validateSchematicName(String name)
|
||||||
@@ -203,11 +212,11 @@ public class DungeonHelper
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Check if the dungeon type is valid
|
//Check if the dungeon type is valid
|
||||||
if (!dungeonTypeChecker.contains(dungeonData[0].toLowerCase()))
|
if (!validateDungeonType(dungeonData[0]))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Check if the name is valid
|
//Check if the name is valid
|
||||||
if (!SchematicNamePattern.matcher(dungeonData[1]).matches())
|
if (!SCHEMATIC_NAME_PATTERN.matcher(dungeonData[1]).matches())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Check if the open/closed flag is present
|
//Check if the open/closed flag is present
|
||||||
@@ -246,14 +255,14 @@ public class DungeonHelper
|
|||||||
//Strip off the file extension while splitting the file name
|
//Strip off the file extension while splitting the file name
|
||||||
String[] dungeonData = name.substring(0, name.length() - SCHEMATIC_FILE_EXTENSION.length()).split("_");
|
String[] dungeonData = name.substring(0, name.length() - SCHEMATIC_FILE_EXTENSION.length()).split("_");
|
||||||
|
|
||||||
String dungeonType = dungeonData[0].toLowerCase();
|
DungeonType dungeonType = RuinsPack.getType(dungeonData[0]);
|
||||||
boolean isOpen = dungeonData[2].equalsIgnoreCase("open");
|
boolean isOpen = dungeonData[2].equalsIgnoreCase("open");
|
||||||
int weight = (dungeonData.length == 4) ? Integer.parseInt(dungeonData[3]) : DEFAULT_DUNGEON_WEIGHT;
|
int weight = (dungeonData.length == 4) ? Integer.parseInt(dungeonData[3]) : DEFAULT_DUNGEON_WEIGHT;
|
||||||
|
|
||||||
//Add this custom dungeon to the list corresponding to its type
|
//Add this custom dungeon to the list corresponding to its type
|
||||||
DungeonGenerator generator = new DungeonGenerator(weight, path, isOpen);
|
DungeonGenerator generator = new DungeonGenerator(weight, path, isOpen, dungeonType);
|
||||||
|
|
||||||
dungeonTypeMapping.get(dungeonType).add(generator);
|
RuinsPack.addDungeon(generator);
|
||||||
registeredDungeons.add(generator);
|
registeredDungeons.add(generator);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
{
|
{
|
||||||
@@ -266,7 +275,7 @@ public class DungeonHelper
|
|||||||
{
|
{
|
||||||
System.out.println("Could not parse dungeon filename, not adding dungeon to generation lists");
|
System.out.println("Could not parse dungeon filename, not adding dungeon to generation lists");
|
||||||
}
|
}
|
||||||
untaggedDungeons.add(new DungeonGenerator(DEFAULT_DUNGEON_WEIGHT, path, true));
|
untaggedDungeons.add(new DungeonGenerator(DEFAULT_DUNGEON_WEIGHT, path, true, DungeonType.UNKNOWN_TYPE));
|
||||||
System.out.println("Registered untagged dungeon: " + name);
|
System.out.println("Registered untagged dungeon: " + name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -277,7 +286,7 @@ public class DungeonHelper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void importCustomDungeons(String path)
|
private void registerCustomDungeons(String path)
|
||||||
{
|
{
|
||||||
File directory = new File(path);
|
File directory = new File(path);
|
||||||
File[] schematicNames = directory.listFiles();
|
File[] schematicNames = directory.listFiles();
|
||||||
@@ -298,9 +307,9 @@ public class DungeonHelper
|
|||||||
{
|
{
|
||||||
//Register the core schematics
|
//Register the core schematics
|
||||||
//These are used for debugging and in case of unusual errors while loading dungeons
|
//These are used for debugging and in case of unusual errors while loading dungeons
|
||||||
defaultUp = new DungeonGenerator(DEFAULT_DUNGEON_WEIGHT, DEFAULT_UP_SCHEMATIC_PATH, true);
|
defaultUp = new DungeonGenerator(DEFAULT_DUNGEON_WEIGHT, DEFAULT_UP_SCHEMATIC_PATH, true, DungeonType.UNKNOWN_TYPE);
|
||||||
defaultDown = new DungeonGenerator(DEFAULT_DUNGEON_WEIGHT, DEFAULT_DOWN_SCHEMATIC_PATH, true);
|
defaultDown = new DungeonGenerator(DEFAULT_DUNGEON_WEIGHT, DEFAULT_DOWN_SCHEMATIC_PATH, true, DungeonType.UNKNOWN_TYPE);
|
||||||
defaultError = new DungeonGenerator(DEFAULT_DUNGEON_WEIGHT, DEFAULT_ERROR_SCHEMATIC_PATH, true);
|
defaultError = new DungeonGenerator(DEFAULT_DUNGEON_WEIGHT, DEFAULT_ERROR_SCHEMATIC_PATH, true, DungeonType.UNKNOWN_TYPE);
|
||||||
|
|
||||||
//Open the list of dungeons packaged with our mod and register their schematics
|
//Open the list of dungeons packaged with our mod and register their schematics
|
||||||
InputStream listStream = this.getClass().getResourceAsStream(BUNDLED_DUNGEONS_LIST_PATH);
|
InputStream listStream = this.getClass().getResourceAsStream(BUNDLED_DUNGEONS_LIST_PATH);
|
||||||
@@ -408,7 +417,7 @@ public class DungeonHelper
|
|||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<DungeonGenerator> getDungeonChainHistory(DimData dimData, int maxSize)
|
public static ArrayList<DungeonGenerator> getDungeonChainHistory(DimData dimData, DungeonPack pack, int maxSize)
|
||||||
{
|
{
|
||||||
//TODO: I've improved this code for the time being. However, searching across links is a flawed approach. A player could
|
//TODO: I've improved this code for the time being. However, searching across links is a flawed approach. A player could
|
||||||
//manipulate the output of this function by setting up links to mislead our algorithm or by removing links.
|
//manipulate the output of this function by setting up links to mislead our algorithm or by removing links.
|
||||||
@@ -418,10 +427,15 @@ public class DungeonHelper
|
|||||||
ArrayList<DungeonGenerator> history = new ArrayList<DungeonGenerator>();
|
ArrayList<DungeonGenerator> history = new ArrayList<DungeonGenerator>();
|
||||||
DimData tailDim = helper.getDimData(helper.getLinkDataFromCoords(dimData.exitDimLink.destXCoord, dimData.exitDimLink.destYCoord, dimData.exitDimLink.destZCoord, dimData.exitDimLink.destDimID).destDimID);
|
DimData tailDim = helper.getDimData(helper.getLinkDataFromCoords(dimData.exitDimLink.destXCoord, dimData.exitDimLink.destYCoord, dimData.exitDimLink.destZCoord, dimData.exitDimLink.destDimID).destDimID);
|
||||||
|
|
||||||
for (int count = 0; count < maxSize && tailDim.dungeonGenerator != null; count++)
|
for (int count = 0; count < maxSize; count++)
|
||||||
{
|
{
|
||||||
history.add(tailDim.dungeonGenerator);
|
if (tailDim.dungeonGenerator == null || tailDim.dungeonGenerator.getDungeonType().Owner != pack)
|
||||||
|
{
|
||||||
|
//We've reached a dimension that doesn't belong to our pack. Stop the search here.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
history.add(tailDim.dungeonGenerator);
|
||||||
if (count + 1 < maxSize)
|
if (count + 1 < maxSize)
|
||||||
{
|
{
|
||||||
for (LinkData link : tailDim.getLinksInDim())
|
for (LinkData link : tailDim.getLinksInDim())
|
||||||
|
|||||||
@@ -17,11 +17,15 @@ public class WeightedContainer<T> extends WeightedRandomItem {
|
|||||||
{
|
{
|
||||||
super(weight);
|
super(weight);
|
||||||
this.data = data;
|
this.data = data;
|
||||||
super.itemWeight = weight;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public T getData()
|
public T getData()
|
||||||
{
|
{
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public WeightedContainer<T> clone()
|
||||||
|
{
|
||||||
|
return new WeightedContainer<T>(data, itemWeight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user