Fixed Public and Private pocket sizes

-Fixed configured Public and Private pocket sizes not being taken into
account when loading the game, and thus, when placing down pocket
schematics.
-Added config option to force-load all available schematics.

-Made Editing config defaults easier, by automatically adjusting
description strings.
-Changed dimensionranges functionality to use a bit more of Forge's
native functionality and only 1 list instead of two of which 1 would be
guaranteedly unused.
This commit is contained in:
Robijnvogel 2018-01-13 20:03:12 +01:00
parent dde38384fa
commit e8e8794811
3 changed files with 105 additions and 66 deletions

View file

@ -20,7 +20,11 @@ public final class Config {
@Getter private static int maxPocketSize = 15;
@Getter private static int privatePocketSize = 3;
@Getter private static int publicPocketSize = 2;
@Getter private static boolean loadAllSchematics = false;
@Getter private static int baseDim = 684;
// TODO: Remove these config options?
@Getter private static int maxDungeonDepth = 100;
@Getter private static int owCoordinateOffsetBase = 64;
@Getter private static double owCoordinateOffsetPower = 1.3;
@ -30,12 +34,13 @@ public final class Config {
@Getter private static boolean dangerousLimboMonolithsEnabled = false;
@Getter private static boolean monolithTeleportationEnabled = true;
@Getter private static int clusterGenerationChance;
@Getter private static int gatewayGenerationChance;
@Getter private static int clusterGenerationChance = 2;
@Getter private static int gatewayGenerationChance = 15;
@Getter private static boolean limboEscapeEnabled;
@Getter private static boolean universalLimboEnabled;
@Getter private static boolean limboEscapeEnabled = true;
@Getter private static boolean universalLimboEnabled = false;
// TODO: more complex functionality should be moved from the config class
@Getter private static DimensionFilter riftClusterDimensions;
@Getter private static DimensionFilter riftGatewayDimensions;
@ -66,20 +71,20 @@ public final class Config {
// Setup general
config.addCustomCategoryComment("general", "General configuration options.");
Property prop = config.get("general", "baseDim", baseDim,
"Dimension ID of the first Dimensional Doors dimension. Other dimensions will use consecutive IDs. NB: If you change this after creating a world, you may lose these dimensions. [default: 684]");
"Dimension ID of the first Dimensional Doors dimension. Other dimensions will use consecutive IDs. NB: If you change this after creating a world, you may lose these dimensions. [default: "+baseDim+"]");
baseDim = prop.getInt(baseDim);
//Dungeons
config.addCustomCategoryComment("dungeons", "The following options will determine the depths, wandering offsets and contents of Dungeon Pockets.");
maxDungeonDepth = setConfigIntWithMaxAndMin(config, "dungeons", "maxDungeonDepth", maxDungeonDepth,
"Sets the maximum (deepest) depth that a dungeon pocket can be at. [min: 1, max: 32, default: 8]", 1, 32);
"Sets the maximum (deepest) depth that a dungeon pocket can be at. [min: 1, max: 128, default: "+maxDungeonDepth+"]", 1, 128);
owCoordinateOffsetBase = setConfigIntWithMaxAndMin(config, "dungeons", "owCoordinateOffsetBase", owCoordinateOffsetBase,
"Determines how heavy the depth weighs when determining the overworld coordinates corresponding to a dungeon pocket. [min: 1, max: 128, default: 64]", 1, 128);
"Determines how heavy the depth weighs when determining the overworld coordinates corresponding to a dungeon pocket. [min: 1, max: 128, default: "+owCoordinateOffsetBase+"]", 1, 128);
prop = config.get("dungeons", "owCoordinateOffsetPower", owCoordinateOffsetPower,
"Determines how heavy the depth weighs when determining the overworld coordinates corresponding to a dungeon pocket. [default: 1.3]"
"Determines how heavy the depth weighs when determining the overworld coordinates corresponding to a dungeon pocket. [default: "+owCoordinateOffsetPower+"]"
+ System.getProperty("line.separator") + "max offset = (depth * owCoordinateOffsetBase)^owCoordinateOffsetPower");
owCoordinateOffsetPower = prop.getDouble(owCoordinateOffsetPower);
@ -95,55 +100,62 @@ public final class Config {
//Monoliths
config.addCustomCategoryComment("monoliths", "How dangerous are Monoliths");
prop = config.get("monoliths", "dangerousLimboMonoliths", dangerousLimboMonolithsEnabled,
"Are Monoliths in Limbo Dangerous? [default: false]");
"Are Monoliths in Limbo Dangerous? [default: "+dangerousLimboMonolithsEnabled+"]");
dangerousLimboMonolithsEnabled = prop.getBoolean();
prop = config.get("monoliths", "monolithTeleportation", monolithTeleportationEnabled,
"Is Monolith Teleportation enabled? [default: true]");
"Is Monolith Teleportation enabled? [default: "+monolithTeleportationEnabled+"]");
monolithTeleportationEnabled = prop.getBoolean();
//Pocket Dimensions
config.addCustomCategoryComment("pocket_dimension", "The following values determine the maximum sizes of different kinds of pockets. These values will only influence new worlds.");
pocketGridSize = setConfigIntWithMaxAndMin(config, "pocket_dimension", "pocketGridSize", pocketGridSize,
"Sets how many chunks apart all pockets in pocket dimensions should be placed. [min: 4, max: 32, default: 32]", 4, 32);
"Sets how many chunks apart all pockets in pocket dimensions should be placed. [min: 4, max: 32, default: "+pocketGridSize+"]", 4, 32);
maxPocketSize = setConfigIntWithMaxAndMin(config, "pocket_dimension", "maxPocketSize", maxPocketSize,
"Sets how deep and wide any pocket can be. [min: 0, max: pocketGridSize/2, default: 4]", 0, (int) ((double) pocketGridSize / 2 - 0.5));
"Sets how deep and wide any pocket can be. [min: 0, max: pocketGridSize/2, default: "+maxPocketSize+"]", 0, (int) ((double) pocketGridSize / 2 - 0.5));
privatePocketSize = setConfigIntWithMaxAndMin(config, "pocket_dimension", "privatePocketSize", privatePocketSize,
"Sets how deep and wide any personal pocket can be. [min: 0, max: maxPocketSize, default: 3]", 0, maxPocketSize);
"Sets how deep and wide any personal pocket can be. [min: 0, max: maxPocketSize, default: "+privatePocketSize+"]", 0, maxPocketSize);
publicPocketSize = setConfigIntWithMaxAndMin(config, "pocket_dimension", "publicPocketSize", publicPocketSize,
"Sets how deep and wide any public pocket can be. [min: 0, max: maxPocketSize, default: 2]", 0, maxPocketSize);
"Sets how deep and wide any public pocket can be. [min: 0, max: maxPocketSize, default: "+publicPocketSize+"]", 0, maxPocketSize);
loadAllSchematics =config.get("pocket_dimension", "loadAllSchematics", loadAllSchematics,
"Forces all available pocket schematics to load on game-start even if the configured maximum sizes mean that these " +
"schematics will never be placed in any naturally generated pockets. This is meant for testing purposes, " +
"because the //pocket command can be used to force generate these pockets. " +
"The default value is "+loadAllSchematics+".").getBoolean(loadAllSchematics);
clusterGenerationChance = config.get(Configuration.CATEGORY_GENERAL, "Cluster Generation Chance", 2,
clusterGenerationChance = config.get(CATEGORY_WORLD_GENERATION, "clusterGenerationChance", clusterGenerationChance,
"Sets the chance (out of " + GatewayGenerator.MAX_CLUSTER_GENERATION_CHANCE + ") that a cluster of rifts will " +
"generate in a given chunk. The default chance is 2.").getInt();
"generate in a given chunk. The default chance is "+clusterGenerationChance+".").getInt(clusterGenerationChance);
gatewayGenerationChance = config.get(Configuration.CATEGORY_GENERAL, "Gateway Generation Chance", 15,
gatewayGenerationChance = config.get(CATEGORY_WORLD_GENERATION, "gatewayGenerationChance", gatewayGenerationChance,
"Sets the chance (out of " + GatewayGenerator.MAX_GATEWAY_GENERATION_CHANCE + ") that a Rift Gateway will " +
"generate in a given chunk. The default chance is 15.").getInt();
"generate in a given chunk. The default chance is "+gatewayGenerationChance+".").getInt(gatewayGenerationChance);
//World Generation
config.addCustomCategoryComment(CATEGORY_WORLD_GENERATION,
"The following settings require lists of dimensions in a specific format. " +
"A list must consist of ranges separated by commas. A range may be a single number to indicate " +
"just one dimension or two numbers in the form \"X - Y\". Spaces are permitted " +
"but not required. Example: -100, -10 - -1, 20 - 30");
"The following settings require lists of dimension ranges in a specific format. "
+ "A dimension range may be a single number to indicate just one dimension "
+ "or two numbers in the form \"X - Y\". Spaces are permitted but not required. "
+ "Examples: -1, 1, -1 - 1, -1-1. "
+ "Separate dimension ranges need to be on a new line.");
riftClusterDimensions = loadFilter(config, "Rift Cluster", "Rift Clusters");
riftGatewayDimensions = loadFilter(config, "Rift Gateway", "Rift Gateways");
riftClusterDimensions = loadFilter(config, "cluster", "Rift Clusters");
riftGatewayDimensions = loadFilter(config, "gateway", "Rift Gateways");
limboEscapeEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Limbo Escape", true,
limboEscapeEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Limbo Escape", limboEscapeEnabled,
"Sets whether players are teleported out of Limbo when walking over the Eternal Fabric that " +
"generates near the bottom of the dimension. If disabled, players could still leave through " +
"dungeons in Limbo or by dying (if Hardcore Limbo is disabled). The default value is true.").getBoolean(true);
"dungeons in Limbo or by dying (if Hardcore Limbo is disabled). The default value is "+limboEscapeEnabled+".").getBoolean(limboEscapeEnabled);
universalLimboEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Universal Limbo", false,
universalLimboEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Universal Limbo", universalLimboEnabled,
"Sets whether players are teleported to Limbo when they die in any dimension (except Limbo). " +
"Normally, players only go to Limbo if they die in a pocket dimension. This setting will not " +
"affect deaths in Limbo, which can be set with the Hardcore Limbo option. " +
"The default value is false.").getBoolean(false);
"The default value is "+universalLimboEnabled+".").getBoolean(universalLimboEnabled);
// Save config
config.save();
@ -166,26 +178,28 @@ public final class Config {
}
}
private static DimensionFilter loadFilter(Configuration config, String prefix, String description) {
boolean enableBlacklist = config.get(CATEGORY_WORLD_GENERATION, "Enable " + prefix + " Blacklist", true,
"Sets whether " + description + " will not generate in certain blacklisted dimensions. " +
"If set to false, then " + description + " will follow a whitelist instead.").getBoolean(true);
private static DimensionFilter loadFilter(Configuration config, String prefix, String featureName) {
//default values
boolean enableBlacklist = true;
String enableName = prefix + "Blacklist";
String listName = prefix + "DimRangeList";
String[] list = new String[0];
enableBlacklist = config.get(CATEGORY_WORLD_GENERATION, enableName, enableBlacklist,
"Sets whether " + listName + " is a blacklist or not." + "The default value is "+enableBlacklist+".").getBoolean(enableBlacklist);
String whitelist = config.get(CATEGORY_WORLD_GENERATION, prefix + " Whitelist", "",
"A list of the only dimensions in which " + description + " may generate.").getString();
String blacklist = config.get(CATEGORY_WORLD_GENERATION, prefix + " Blacklist", "",
"A list of dimensions in which " + description + " may not generate.").getString();
list = config.get(CATEGORY_WORLD_GENERATION, listName, list,
"A list including/excluding the dimensions in which " + featureName + " may generate, depending on " + enableName + ".").getStringList();
try {
if (enableBlacklist) {
return DimensionFilter.parseBlacklist(blacklist);
return DimensionFilter.parseBlacklist(list);
} else {
return DimensionFilter.parseWhitelist(whitelist);
return DimensionFilter.parseWhitelist(list);
}
} catch (Exception inner) {
throw new RuntimeException("An error occurred while loading a whitelist or blacklist setting for " +
description + ". Please make sure that your configuration file is set up correctly.", inner);
featureName + ". Please make sure that your configuration file is set up correctly.", inner);
}
}
}

View file

@ -26,18 +26,20 @@ import org.dimdev.dimdoors.shared.tools.SchematicConverter;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.CompressedStreamTools;
import org.apache.commons.io.IOUtils;
import org.dimdev.dimdoors.shared.pockets.PocketRegistry;
import org.dimdev.dimdoors.shared.world.ModDimensions;
/**
* @author Robijnvogel
*/
public class SchematicHandler { // TODO: make this more general (not dimdoors-related)
public static final SchematicHandler INSTANCE = new SchematicHandler(); // TODO: make static
private List<PocketTemplate> templates;
private Map<String, Map<String, Integer>> nameMap; // group -> name -> index in templates
// LOADING CODE STARTS HERE <editor-fold>
public void loadSchematics() {
templates = new ArrayList<>();
@ -83,11 +85,9 @@ public class SchematicHandler { // TODO: make this more general (not dimdoors-re
JsonParser parser = new JsonParser();
JsonElement jsonElement = parser.parse(jsonString);
JsonObject jsonTemplate = jsonElement.getAsJsonObject();
//DimDoors.log.info("Checkpoint 1 reached");
//Generate and get templates (without a schematic) of all variations that are valid for the current "maxPocketSize"
List<PocketTemplate> validTemplates = getAllValidVariations(jsonTemplate);
//DimDoors.log.info("Checkpoint 4 reached; " + validTemplates.size() + " templates were loaded");
String subDirectory = jsonTemplate.get("group").getAsString(); //get the subfolder in which the schematics are stored
@ -139,7 +139,7 @@ public class SchematicHandler { // TODO: make this more general (not dimdoors-re
}
schematicDataStream.close();
} catch (IOException ex) {
Logger.getLogger(SchematicHandler.class.getName()).log(Level.SEVERE, "Schematic file for " + template.getName() + " could not be read as a valid schematic NBT file.", ex);
Logger.getLogger(SchematicHandler.class.getName()).log(Level.SEVERE, "Schematic file for " + template.getName() + " could not be read as a valid schematic NBT file.", ex); // TODO: consistently use one type of logger for this.
} finally {
try {
schematicDataStream.close();
@ -164,6 +164,21 @@ public class SchematicHandler { // TODO: make this more general (not dimdoors-re
List<PocketTemplate> pocketTemplates = new ArrayList<>();
final String directory = jsonTemplate.get("group").getAsString();
int maxSize = -1;
if (!Config.isLoadAllSchematics()) {
switch (directory) {
case "public":
maxSize = Config.getPublicPocketSize(); // TODO: hardcode?¿
break;
case "private":
maxSize = Config.getPrivatePocketSize();
break;
default:
maxSize = Config.getMaxPocketSize();
break;
}
}
final JsonArray variations = jsonTemplate.getAsJsonArray("variations");
//convert the variations arraylist to a list of pocket templates
@ -171,6 +186,9 @@ public class SchematicHandler { // TODO: make this more general (not dimdoors-re
JsonObject variation = variationElement.getAsJsonObject();
String variantName = variation.get("variantName").getAsString();
int variationSize = variation.get("size").getAsInt();
if (maxSize >= 0 && variationSize > maxSize) {
continue;
}
int minDepth = variation.get("minDepth").getAsInt();
int maxDepth = variation.get("maxDepth").getAsInt();
JsonArray weightsJsonArray = variation.get("weights").getAsJsonArray();
@ -210,7 +228,6 @@ public class SchematicHandler { // TODO: make this more general (not dimdoors-re
}
// LOADING CODE ENDS HERE </editor-fold>
public Set<String> getTemplateGroups() {
return nameMap.keySet();
}
@ -232,9 +249,13 @@ public class SchematicHandler { // TODO: make this more general (not dimdoors-re
*/
public PocketTemplate getTemplate(String group, String name) {
Map<String, Integer> groupMap = nameMap.get(group);
if(groupMap == null) return null;
if (groupMap == null) {
return null;
}
Integer index = groupMap.get(name);
if(index == null) return null;
if (index == null) {
return null;
}
return templates.get(index);
}
@ -258,7 +279,8 @@ public class SchematicHandler { // TODO: make this more general (not dimdoors-re
* @param group
* @param depth
* @param maxSize Maximum size the template can be.
* @param getLargest Setting this to true will always get the largest template size in that group, but still randomly out of the templates with that size (ex. for private pockets)
* @param getLargest Setting this to true will always get the largest template size in that group,
* but still randomly out of the templates with that size (ex. for private and public pockets)
* @return A random template matching those criteria, or null if none were found
*/
public PocketTemplate getRandomTemplate(String group, int depth, int maxSize, boolean getLargest) {
@ -268,7 +290,7 @@ public class SchematicHandler { // TODO: make this more general (not dimdoors-re
for (PocketTemplate template : templates) {
if (template.getGroupName().equals(group)
&& (depth == -1 || depth >= template.getMinDepth() && (depth <= template.getMaxDepth() || template.getMaxDepth() == -1))
&& (maxSize == -1 || template.getSize() < maxSize)) {
&& (maxSize == -1 || template.getSize() <= maxSize)) {
if (getLargest && template.getSize() > largestSize) {
weightedTemplates = new HashMap<>();
largestSize = template.getSize();
@ -276,7 +298,7 @@ public class SchematicHandler { // TODO: make this more general (not dimdoors-re
weightedTemplates.put(template, template.getWeight(depth));
}
}
if (weightedTemplates.size() == 0) {
if (weightedTemplates.isEmpty()) {
DimDoors.log.warn("getRandomTemplate failed, no templates matching those criteria were found.");
return null; // TODO: switch to exception system
}
@ -285,11 +307,11 @@ public class SchematicHandler { // TODO: make this more general (not dimdoors-re
}
public PocketTemplate getPersonalPocketTemplate() {
return getRandomTemplate("private", -1, Config.getMaxPocketSize(), true); // TODO: config option for getLargest
return getRandomTemplate("private", -1, Math.min(Config.getPrivatePocketSize(), PocketRegistry.getForDim(ModDimensions.getPrivateDim()).getPrivatePocketSize()), true);
}
public PocketTemplate getPublicPocketTemplate() {
return getRandomTemplate("public", -1, Config.getMaxPocketSize(), true); // TODO: config option for getLargest
return getRandomTemplate("public", -1, Math.min(Config.getPublicPocketSize(), PocketRegistry.getForDim(ModDimensions.getPublicDim()).getPublicPocketSize()), true);
}
public void saveSchematic(Schematic schematic, String name) {

View file

@ -20,7 +20,7 @@ public class DimensionFilter {
return blacklist.contains(dimensionID);
}
private static RangeSet<Integer> parseRangeSet(String list) {
private static RangeSet<Integer> parseRangeSet(String[] list) {
int index;
int start;
int end;
@ -29,22 +29,25 @@ public class DimensionFilter {
String[] intervals;
RangeSet<Integer> ranges = TreeRangeSet.create();
// Strip out all whitespace characters
list = list.replaceAll("\\s", "");
if (list.isEmpty()) {
return ranges;
}
intervals = list.split(",");
// Iterate over all the interval strings
for (String interval : intervals) {
for (String interval : list) {
if (interval == null) {
continue;
}
// Strip out all whitespace characters
interval.replaceAll("\\s", "");
if (interval.isEmpty()) {
continue;
}
// Check if the interval contains a minus sign after the first character
// That indicates that we're dealing with an interval and not a single number
if (interval.length() > 1) {
index = interval.indexOf("-", 1);
} else {
index = -1;
} try {
}
try {
if (index >= 0) {
// Parse this as a range with two values as endpoints
startPart = interval.substring(0, index);
@ -57,7 +60,7 @@ public class DimensionFilter {
end = start;
}
// Add the interval to the set of intervals
ranges.add( Range.closed(start, end) );
ranges.add(Range.closed(start, end));
} catch (Exception e) {
throw new IllegalArgumentException("\"" + interval + "\" is not a valid value or range for dimension IDs");
}
@ -66,11 +69,11 @@ public class DimensionFilter {
return ranges;
}
public static DimensionFilter parseWhitelist(String list) {
public static DimensionFilter parseWhitelist(String[] list) {
return new DimensionFilter(parseRangeSet(list).complement());
}
public static DimensionFilter parseBlacklist(String list) {
public static DimensionFilter parseBlacklist(String[] list) {
return new DimensionFilter(parseRangeSet(list));
}
}
}