Merge pull request #69 from SenseiKiwi/DungeonPacks
Progress on Implementing Dungeon Packs
This commit is contained in:
commit
8c0c89c79e
5 changed files with 467 additions and 74 deletions
|
@ -46,32 +46,26 @@ public class EventHookContainer
|
|||
dimHelper.instance.interDimLinkList.clear();
|
||||
dimHelper.instance.initPockets();
|
||||
}
|
||||
for (Integer ids : dimHelper.getIDs())
|
||||
{
|
||||
World world = dimHelper.getWorld(ids);
|
||||
|
||||
//TODO: In the future, we should iterate over DimHelper's dimension list. We ignore other dimensions anyway.
|
||||
for (int dimensionID : dimHelper.getIDs())
|
||||
{
|
||||
World world = dimHelper.getWorld(dimensionID);
|
||||
int linkCount = 0;
|
||||
|
||||
if (dimHelper.dimList.containsKey(world.provider.dimensionId))
|
||||
if (dimHelper.dimList.containsKey(dimensionID))
|
||||
{
|
||||
//TODO added temporary Try/catch block to prevent a crash here, getLinksInDim needs to be looked at
|
||||
try
|
||||
{
|
||||
for (LinkData link:dimHelper.instance.getDimData(world.provider.dimensionId).getLinksInDim())
|
||||
{
|
||||
if (!mod_pocketDim.blockRift.isBlockImmune(world, link.locXCoord, link.locYCoord, link.locZCoord))
|
||||
{
|
||||
dimHelper.getWorld(link.locDimID).setBlock(link.locXCoord, link.locYCoord, link.locZCoord, properties.RiftBlockID);
|
||||
}
|
||||
linkCount++;
|
||||
if (linkCount >= 100)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
for (LinkData link : dimHelper.instance.getDimData(dimensionID).getLinksInDim())
|
||||
{
|
||||
e.printStackTrace();
|
||||
if (!mod_pocketDim.blockRift.isBlockImmune(world, link.locXCoord, link.locYCoord, link.locZCoord))
|
||||
{
|
||||
world.setBlock(link.locXCoord, link.locYCoord, link.locZCoord, properties.RiftBlockID);
|
||||
}
|
||||
linkCount++;
|
||||
if (linkCount >= 100)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,10 @@ public class DungeonPackConfig
|
|||
private String name;
|
||||
private ArrayList<String> typeNames;
|
||||
private boolean allowDuplicatesInChain;
|
||||
private boolean allowPackChangeIn;
|
||||
private boolean allowPackChangeOut;
|
||||
private boolean distortDoorCoordinates;
|
||||
private int packWeight;
|
||||
private ArrayList<DungeonChainRuleDefinition> rules;
|
||||
|
||||
public DungeonPackConfig() { }
|
||||
|
@ -17,6 +21,10 @@ public class DungeonPackConfig
|
|||
this.name = source.name;
|
||||
this.typeNames = (ArrayList<String>) source.typeNames.clone();
|
||||
this.allowDuplicatesInChain = source.allowDuplicatesInChain;
|
||||
this.allowPackChangeIn = source.allowPackChangeIn;
|
||||
this.allowPackChangeOut = source.allowPackChangeOut;
|
||||
this.distortDoorCoordinates = source.distortDoorCoordinates;
|
||||
this.packWeight = source.packWeight;
|
||||
this.rules = (ArrayList<DungeonChainRuleDefinition>) source.rules.clone();
|
||||
}
|
||||
|
||||
|
@ -75,4 +83,44 @@ public class DungeonPackConfig
|
|||
{
|
||||
return rules;
|
||||
}
|
||||
|
||||
public boolean allowPackChangeIn()
|
||||
{
|
||||
return allowPackChangeIn;
|
||||
}
|
||||
|
||||
public void setAllowPackChangeIn(boolean value)
|
||||
{
|
||||
this.allowPackChangeIn = value;
|
||||
}
|
||||
|
||||
public boolean allowPackChangeOut()
|
||||
{
|
||||
return allowPackChangeOut;
|
||||
}
|
||||
|
||||
public void setAllowPackChangeOut(boolean value)
|
||||
{
|
||||
this.allowPackChangeOut = value;
|
||||
}
|
||||
|
||||
public int getPackWeight()
|
||||
{
|
||||
return packWeight;
|
||||
}
|
||||
|
||||
public void setPackWeight(int packWeight)
|
||||
{
|
||||
this.packWeight = packWeight;
|
||||
}
|
||||
|
||||
public boolean getDistortDoorCoordinates()
|
||||
{
|
||||
return distortDoorCoordinates;
|
||||
}
|
||||
|
||||
public void setDistortDoorCoordinates(boolean value)
|
||||
{
|
||||
this.distortDoorCoordinates = value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,385 @@
|
|||
package StevenDimDoors.mod_pocketDim.dungeon.pack;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import StevenDimDoors.mod_pocketDim.util.BaseConfigurationProcessor;
|
||||
import StevenDimDoors.mod_pocketDim.util.ConfigurationProcessingException;
|
||||
import StevenDimDoors.mod_pocketDim.util.WeightedContainer;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.primitives.Ints;
|
||||
|
||||
public class DungeonPackConfigReader extends BaseConfigurationProcessor<DungeonPackConfig>
|
||||
{
|
||||
private interface ILineProcessor
|
||||
{
|
||||
public void process(String line, DungeonPackConfig config) throws ConfigurationProcessingException;
|
||||
}
|
||||
|
||||
//Note: These constants aren't static so that the memory will be released once
|
||||
//we're done using it an instance. These aren't objects that we need to hold
|
||||
//onto throughout the lifetime of MC, only at loading time.
|
||||
|
||||
private final int CONFIG_VERSION = 1;
|
||||
private final int LOOKAHEAD_LIMIT = 1024;
|
||||
private final int MAX_PRODUCT_WEIGHT = 10000;
|
||||
private final int DEFAULT_PRODUCT_WEIGHT = 100;
|
||||
private final int MAX_DUNGEON_PACK_WEIGHT = 10000;
|
||||
private final int DEFAULT_DUNGEON_PACK_WEIGHT = 100;
|
||||
private final String COMMENT_MARKER = "##";
|
||||
|
||||
private final Pattern DUNGEON_TYPE_PATTERN = Pattern.compile("[A-Za-z0-9_\\-]{1,20}");
|
||||
|
||||
private final Splitter WHITESPACE_SPLITTER = Splitter.on(CharMatcher.WHITESPACE).omitEmptyStrings();
|
||||
private final String SETTING_SEPARATOR = "=";
|
||||
private final String RULE_SEPARATOR = "->";
|
||||
private final String WEIGHT_SEPARATOR = "#";
|
||||
|
||||
public DungeonPackConfigReader() { }
|
||||
|
||||
@Override
|
||||
public DungeonPackConfig readFromStream(InputStream inputStream) throws ConfigurationProcessingException
|
||||
{
|
||||
BufferedReader reader = null;
|
||||
try
|
||||
{
|
||||
DungeonPackConfig config = new DungeonPackConfig();
|
||||
reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
|
||||
//Check the config format version
|
||||
int version = readVersion(reader);
|
||||
if (version != CONFIG_VERSION)
|
||||
{
|
||||
throw new ConfigurationProcessingException("The dungeon pack config has an incompatible version.");
|
||||
}
|
||||
|
||||
config.setTypeNames(new ArrayList<String>());
|
||||
config.setRules(new ArrayList<DungeonChainRuleDefinition>());
|
||||
|
||||
//Read the dungeon types
|
||||
if (findSection("Types", reader))
|
||||
{
|
||||
processLines(reader, config, new DungeonTypeProcessor());
|
||||
}
|
||||
|
||||
//Load default settings
|
||||
config.setAllowDuplicatesInChain(true);
|
||||
config.setAllowPackChangeIn(true);
|
||||
config.setAllowPackChangeOut(true);
|
||||
config.setDistortDoorCoordinates(false);
|
||||
config.setPackWeight(DEFAULT_DUNGEON_PACK_WEIGHT);
|
||||
|
||||
//Read the settings section
|
||||
if (findSection("Settings", reader))
|
||||
{
|
||||
processLines(reader, config, new DungeonSettingsParser());
|
||||
}
|
||||
|
||||
//Read the rules section
|
||||
if (findSection("Rules", reader))
|
||||
{
|
||||
processLines(reader, config, new RuleDefinitionParser());
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
catch (ConfigurationProcessingException ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new ConfigurationProcessingException("An unexpected error occurred while trying to read the configuration file.", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (reader != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
reader.close();
|
||||
}
|
||||
catch (IOException ex) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int readVersion(BufferedReader reader) throws ConfigurationProcessingException, IOException
|
||||
{
|
||||
String firstLine = reader.readLine();
|
||||
String[] parts = firstLine.split("\\s", 0);
|
||||
Integer version = null;
|
||||
|
||||
if (parts.length == 2 && parts[0].equalsIgnoreCase("version"))
|
||||
{
|
||||
version = Ints.tryParse(parts[1]);
|
||||
}
|
||||
|
||||
if (version == null)
|
||||
{
|
||||
throw new ConfigurationProcessingException("Could not parse the config format version.");
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
private void processLines(BufferedReader reader, DungeonPackConfig config, ILineProcessor processor) throws IOException, ConfigurationProcessingException
|
||||
{
|
||||
String line;
|
||||
|
||||
while (reader.ready())
|
||||
{
|
||||
reader.mark(LOOKAHEAD_LIMIT);
|
||||
line = reader.readLine();
|
||||
if (!line.startsWith(COMMENT_MARKER))
|
||||
{
|
||||
line = line.trim();
|
||||
if (line.length() > 0)
|
||||
{
|
||||
if (line.endsWith(":"))
|
||||
{
|
||||
//Consider this line a section header, reset the reader to undo consuming it
|
||||
reader.reset();
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
processor.process(line, config);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean findSection(String name, BufferedReader reader) throws IOException, ConfigurationProcessingException
|
||||
{
|
||||
boolean found = false;
|
||||
boolean matched = false;
|
||||
String line = null;
|
||||
String label = name + ":";
|
||||
|
||||
//Find the next section header
|
||||
//Ignore blank lines and comment lines, stop for headers, and throw an exception for anything else
|
||||
while (!found && reader.ready())
|
||||
{
|
||||
reader.mark(LOOKAHEAD_LIMIT);
|
||||
line = reader.readLine();
|
||||
if (!line.startsWith(COMMENT_MARKER))
|
||||
{
|
||||
line = line.trim();
|
||||
if (line.length() > 0)
|
||||
{
|
||||
if (line.endsWith(":"))
|
||||
{
|
||||
//Consider this line a section header
|
||||
found = true;
|
||||
matched = line.equalsIgnoreCase(label);
|
||||
}
|
||||
else
|
||||
{
|
||||
//This line is invalid
|
||||
throw new ConfigurationProcessingException("The dungeon pack config has an incorrect line where a section was expected: " + line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Check if the header matches the one we're looking for.
|
||||
//If it doesn't match, undo consuming the line so it can be read later.
|
||||
if (found && !matched)
|
||||
{
|
||||
reader.reset();
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
private class DungeonTypeProcessor implements ILineProcessor
|
||||
{
|
||||
public void process(String line, DungeonPackConfig config) throws ConfigurationProcessingException
|
||||
{
|
||||
List<String> typeNames = config.getTypeNames();
|
||||
|
||||
//Check if the dungeon type has a name that meets our restrictions
|
||||
if (DUNGEON_TYPE_PATTERN.matcher(line).matches())
|
||||
{
|
||||
//Ignore duplicate dungeon types
|
||||
line = line.toUpperCase();
|
||||
if (!typeNames.contains(line))
|
||||
{
|
||||
typeNames.add(line);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ConfigurationProcessingException("The dungeon pack config has a dungeon type with illegal characters in its name: " + line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class DungeonSettingsParser implements ILineProcessor
|
||||
{
|
||||
public void process(String line, DungeonPackConfig config) throws ConfigurationProcessingException
|
||||
{
|
||||
//The various settings that we support will be hardcoded here.
|
||||
//In the future, if we get more settings, then this should be
|
||||
//refactored to use a more lookup-driven approach.
|
||||
|
||||
boolean valid = true;
|
||||
String[] settingParts = line.split(SETTING_SEPARATOR, 2);
|
||||
if (settingParts.length == 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
String name = settingParts[0];
|
||||
String value = settingParts[1];
|
||||
if (name.equalsIgnoreCase("AllowDuplicatesInChain"))
|
||||
{
|
||||
config.setAllowDuplicatesInChain(parseBoolean(value));
|
||||
}
|
||||
else if (name.equalsIgnoreCase("AllowPackChangeOut"))
|
||||
{
|
||||
config.setAllowPackChangeOut(parseBoolean(value));
|
||||
}
|
||||
else if (name.equalsIgnoreCase("AllowPackChangeIn"))
|
||||
{
|
||||
config.setAllowPackChangeIn(parseBoolean(value));
|
||||
}
|
||||
else if (name.equalsIgnoreCase("DistortDoorCoordinates"))
|
||||
{
|
||||
config.setDistortDoorCoordinates(parseBoolean(value));
|
||||
}
|
||||
else if (name.equalsIgnoreCase("PackWeight"))
|
||||
{
|
||||
int weight = Integer.parseInt(value);
|
||||
if (weight >= 0 && weight <= MAX_DUNGEON_PACK_WEIGHT)
|
||||
{
|
||||
config.setPackWeight(weight);
|
||||
}
|
||||
else
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (!valid)
|
||||
{
|
||||
throw new ConfigurationProcessingException("The dungeon pack config has an invalid setting: " + line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class RuleDefinitionParser implements ILineProcessor
|
||||
{
|
||||
public void process(String definition, DungeonPackConfig config) throws ConfigurationProcessingException
|
||||
{
|
||||
String[] ruleParts;
|
||||
String[] productParts;
|
||||
String ruleCondition;
|
||||
String ruleProduct;
|
||||
ArrayList<String> condition;
|
||||
ArrayList<WeightedContainer<String>> products;
|
||||
List<String> typeNames = config.getTypeNames();
|
||||
|
||||
ruleParts = definition.toUpperCase().split(RULE_SEPARATOR, -1);
|
||||
if (ruleParts.length != 2)
|
||||
{
|
||||
throw new ConfigurationProcessingException("The dungeon pack config has an invalid rule: " + definition);
|
||||
}
|
||||
|
||||
ruleCondition = ruleParts[0];
|
||||
ruleProduct = ruleParts[1];
|
||||
condition = new ArrayList<String>();
|
||||
products = new ArrayList<WeightedContainer<String>>();
|
||||
|
||||
for (String typeName : WHITESPACE_SPLITTER.split(ruleCondition))
|
||||
{
|
||||
if (isKnownDungeonType(typeName, typeNames))
|
||||
{
|
||||
condition.add(typeName);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ConfigurationProcessingException("The dungeon pack config has a rule condition with an unknown dungeon type: " + typeName);
|
||||
}
|
||||
}
|
||||
|
||||
for (String product : WHITESPACE_SPLITTER.split(ruleProduct))
|
||||
{
|
||||
Integer weight;
|
||||
String typeName;
|
||||
|
||||
productParts = product.split(WEIGHT_SEPARATOR, -1);
|
||||
if (productParts.length > 2 || productParts.length == 0)
|
||||
{
|
||||
throw new ConfigurationProcessingException("The dungeon pack config has a rule with an invalid product: " + product);
|
||||
}
|
||||
|
||||
typeName = productParts[0];
|
||||
if (isKnownDungeonType(typeName, typeNames))
|
||||
{
|
||||
if (productParts.length > 1)
|
||||
{
|
||||
weight = Ints.tryParse(productParts[1]);
|
||||
if (weight == null || (weight > MAX_PRODUCT_WEIGHT) || (weight < 0))
|
||||
{
|
||||
throw new ConfigurationProcessingException("The dungeon pack config has a rule with an invalid product weight: " + product);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
weight = DEFAULT_PRODUCT_WEIGHT;
|
||||
}
|
||||
products.add(new WeightedContainer<String>(typeName, weight));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ConfigurationProcessingException("The dungeon pack config has an unknown dungeon type in a rule: " + typeName);
|
||||
}
|
||||
}
|
||||
config.getRules().add( new DungeonChainRuleDefinition(condition, products) );
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isKnownDungeonType(String typeName, List<String> typeNames)
|
||||
{
|
||||
return typeName.equals(DungeonType.WILDCARD_TYPE.Name) || typeNames.contains(typeName);
|
||||
}
|
||||
|
||||
private static boolean parseBoolean(String value)
|
||||
{
|
||||
if (value.equalsIgnoreCase("true"))
|
||||
return true;
|
||||
if (value.equalsIgnoreCase("false"))
|
||||
return false;
|
||||
throw new IllegalArgumentException("The boolean value must be either \"true\" or \"false\", ignoring case.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canWrite()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToStream(OutputStream outputStream, DungeonPackConfig data) throws ConfigurationProcessingException
|
||||
{
|
||||
throw new UnsupportedOperationException("DungeonPackConfigReader does not support writing.");
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@ import java.io.File;
|
|||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
@ -22,12 +21,12 @@ import StevenDimDoors.mod_pocketDim.DungeonGenerator;
|
|||
import StevenDimDoors.mod_pocketDim.LinkData;
|
||||
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
|
||||
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.DungeonPackConfig;
|
||||
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPackConfigReader;
|
||||
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonType;
|
||||
import StevenDimDoors.mod_pocketDim.items.itemDimDoor;
|
||||
import StevenDimDoors.mod_pocketDim.util.WeightedContainer;
|
||||
import StevenDimDoors.mod_pocketDim.util.ConfigurationProcessingException;
|
||||
|
||||
public class DungeonHelper
|
||||
{
|
||||
|
@ -112,56 +111,21 @@ public class DungeonHelper
|
|||
{
|
||||
//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("? ? ? ? ? ? ? ? -> Trap#20 SimpleHall#40 ComplexHall#10 Exit#20 DeadEnd#10"));
|
||||
|
||||
rules.add(parseDefinitionUnsafe("? ? ? ? -> Trap#18 SimpleHall#40 ComplexHall#10 Exit#18 DeadEnd#10 Hub#4"));
|
||||
|
||||
rules.add(parseDefinitionUnsafe("? ? ? -> ComplexHall Hub Trap SimpleHall Maze"));
|
||||
|
||||
rules.add(parseDefinitionUnsafe("? ? -> ComplexHall Hub Trap SimpleHall Maze"));
|
||||
|
||||
rules.add(parseDefinitionUnsafe("? -> ComplexHall#40 Hub#30 Trap#10 SimpleHall#10 Maze#10"));
|
||||
|
||||
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(" "))
|
||||
|
||||
DungeonPackConfig config;
|
||||
try
|
||||
{
|
||||
if (!conditionPart.isEmpty())
|
||||
condition.add(conditionPart);
|
||||
config = (new DungeonPackConfigReader()).readFromResource("/schematics/ruins/rules.txt");
|
||||
config.setName("ruins");
|
||||
return config;
|
||||
}
|
||||
|
||||
for (String product : parts[1].split(" "))
|
||||
catch (ConfigurationProcessingException e)
|
||||
{
|
||||
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));
|
||||
}
|
||||
//FIXME TEMPORARY DEBUG PRINT, DO SOMETHING BETTER HERE
|
||||
System.err.println("OH GOD SOMETHING WENT WRONG WITH THE DEFAULT DUNGEON PACK CONFIG");
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
return new DungeonChainRuleDefinition(condition, products);
|
||||
}
|
||||
|
||||
public List<DungeonGenerator> getRegisteredDungeons()
|
||||
|
|
|
@ -9,10 +9,12 @@ DeadEnd
|
|||
Maze
|
||||
|
||||
Settings:
|
||||
AllowRepetitionsInBranch = false
|
||||
AllowDuplicatesInChain = false
|
||||
AllowPackChangeOut = true
|
||||
AllowPackChangeIn = true
|
||||
PackWeight = 100
|
||||
DistortDoorCoordinates = true
|
||||
|
||||
## Prevent this pack from being selected for transitioning in once we've transitioned out
|
||||
AllowPackChangeIn = false
|
||||
|
||||
Rules:
|
||||
|
||||
|
|
Loading…
Reference in a new issue