Finished Pocket creation
-Added dependency on Vazkii's Pillar mod for "schematic" loading -Added config directory for DimDoors -Fixed entrance door placement coords -Refractored some methods -Added json-reader functionality -Code compiles now Todo: -Make code added in SchematicHandler more modular -Game gets stuck on world-load. Probably because the default json file for "defaultPersonal" is not available yet at the saves directory.
This commit is contained in:
parent
88dbcf152a
commit
5c383bde1d
4 changed files with 202 additions and 33 deletions
|
@ -33,8 +33,16 @@ minecraft {
|
|||
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
|
||||
}
|
||||
|
||||
repositories {
|
||||
ivy {
|
||||
name "Pillar"
|
||||
artifactPattern "https://addons-origin.cursecdn.com/files/2318/492/[module]-[revision].[ext]"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.flowpowered:flow-math:1.0.3'
|
||||
compile name: 'Pillar', version: '1.0-5', ext: 'jar'
|
||||
}
|
||||
|
||||
processResources
|
||||
|
|
|
@ -5,8 +5,12 @@
|
|||
*/
|
||||
package com.zixiken.dimdoors;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
import net.minecraftforge.common.config.Property;
|
||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||
|
@ -17,11 +21,12 @@ import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
|||
*/
|
||||
public class DDConfig {
|
||||
|
||||
public static File configurationFolder;
|
||||
private static int pocketGridSize = 8;
|
||||
private static int maxPocketSize = 4;
|
||||
private static int privatePocketSize = 3;
|
||||
private static int publicPocketSize = 2;
|
||||
private static String[] dungeonSchematicNames = {"", ""}; //@todo set default dungeon names
|
||||
private static String[] dungeonSchematicNames = {}; //@todo set default dungeon names
|
||||
|
||||
private static int setConfigIntWithMaxAndMin(Configuration config, String category, String key, int defaultValue, String comment, int minValue, int maxValue) {
|
||||
Property prop = config.get(category, key, defaultValue,
|
||||
|
@ -39,6 +44,14 @@ public class DDConfig {
|
|||
public static void loadConfig(FMLPreInitializationEvent event) {
|
||||
|
||||
// Load config
|
||||
configurationFolder = new File(event.getModConfigurationDirectory(), "/DimDoors");
|
||||
if (!configurationFolder.exists()) {
|
||||
try {
|
||||
configurationFolder.createNewFile();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DDConfig.class.getName()).log(Level.SEVERE, "Dimdoors config folder could not be created.", ex);
|
||||
}
|
||||
}
|
||||
Configuration config = new Configuration(event.getSuggestedConfigurationFile());
|
||||
config.load();
|
||||
|
||||
|
|
|
@ -8,14 +8,19 @@ package com.zixiken.dimdoors.shared;
|
|||
import com.zixiken.dimdoors.DimDoors;
|
||||
import com.zixiken.dimdoors.blocks.ModBlocks;
|
||||
import com.zixiken.dimdoors.tileentities.DDTileEntityBase;
|
||||
import java.util.Random;
|
||||
import net.minecraft.block.BlockDoor;
|
||||
import net.minecraft.block.BlockDoor.EnumDoorHalf;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.Rotation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import vazkii.pillar.schema.StructureSchema;
|
||||
import vazkii.pillar.StructureGenerator;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -23,20 +28,26 @@ import net.minecraft.world.World;
|
|||
*/
|
||||
class PocketTemplate { //there is exactly one pocket placer for each different schematic that is loaded into the game (a Json might load several schematics though)
|
||||
|
||||
private final int[] weights; //weights for chanced generation of dungeons per depth level | weights[0] is the weight for depth "minDepth"
|
||||
private final int minDepth;
|
||||
private final int maxDepth;
|
||||
//generation parameters
|
||||
private StructureSchema schematic;
|
||||
private final int size;
|
||||
private final Schematic schematic;
|
||||
private final int entranceDoorX;
|
||||
private final int entranceDoorY;
|
||||
private final int entranceDoorZ;
|
||||
private final EnumPocketType typeID;
|
||||
private final int wallThickness; //determines the thickness of the wall around the pocket. Set to 1 to only generate the "bedRock" outer layer
|
||||
private final int floorThickness;
|
||||
private final int roofThickness;
|
||||
private final EnumPocketType typeID;
|
||||
//selection parameters
|
||||
private final String variantName;
|
||||
private final int minDepth;
|
||||
private final int maxDepth;
|
||||
private final int[] weights; //weights for chanced generation of dungeons per depth level | weights[0] is the weight for depth "minDepth"
|
||||
|
||||
public PocketTemplate(int minDepth, int maxDepth, int[] weights, int size, Schematic schematic, int entranceDoorX, int entranceDoorY, int entranceDoorZ, EnumPocketType typeID, int wallThickness, int floorThickness, int roofThickness) {
|
||||
//this class should contain the actual schematic info, as well as some of the Json info (placement of Rifts and stuff)
|
||||
public PocketTemplate(String variantName, StructureSchema schematic, int size, int entranceDoorX, int entranceDoorY, int entranceDoorZ, int wallThickness, int floorThickness, int roofThickness, EnumPocketType typeID,
|
||||
int minDepth, int maxDepth, int[] weights) {
|
||||
this.variantName = variantName;
|
||||
this.weights = weights; //chance that this Pocket will get generated
|
||||
this.minDepth = minDepth; //pocket will only be generated from this Pocket-depth
|
||||
this.maxDepth = maxDepth; //to this pocket depth
|
||||
|
@ -51,8 +62,11 @@ class PocketTemplate { //there is exactly one pocket placer for each different s
|
|||
this.roofThickness = roofThickness;
|
||||
}
|
||||
|
||||
//@todo about everything
|
||||
//this class should contain the actual schematic info, as well as some of the Json info (placement of Rifts and stuff)
|
||||
public PocketTemplate(String variantName, int size, int entranceDoorX, int entranceDoorY, int entranceDoorZ, int wallThickness, int floorThickness, int roofThickness, EnumPocketType typeID,
|
||||
int minDepth, int maxDepth, int[] weights) {
|
||||
this(variantName, null, size, entranceDoorX, entranceDoorY, entranceDoorZ, wallThickness, floorThickness, roofThickness, typeID, minDepth, maxDepth, weights);
|
||||
}
|
||||
|
||||
int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
@ -64,7 +78,7 @@ class PocketTemplate { //there is exactly one pocket placer for each different s
|
|||
int getMaxDepth() {
|
||||
return maxDepth;
|
||||
}
|
||||
|
||||
|
||||
int getWeight(int depth) {
|
||||
int index = depth - minDepth;
|
||||
if (index >= 0 && index < weights.length) {
|
||||
|
@ -73,6 +87,18 @@ class PocketTemplate { //there is exactly one pocket placer for each different s
|
|||
return 0; //do not generate
|
||||
}
|
||||
|
||||
String getName() {
|
||||
return variantName;
|
||||
}
|
||||
|
||||
Object getSchematic() {
|
||||
return schematic;
|
||||
}
|
||||
|
||||
void setSchematic(StructureSchema schematic) {
|
||||
this.schematic = schematic;
|
||||
}
|
||||
|
||||
int place(int xBase, int yBase, int zBase, int dimID) { //returns the riftID of the entrance DimDoor
|
||||
IBlockState outerWallBlock = ModBlocks.blockDimWall.getStateFromMeta(2); //@todo, does this return the correct wall?
|
||||
IBlockState innerWallBlock;
|
||||
|
@ -85,7 +111,7 @@ class PocketTemplate { //there is exactly one pocket placer for each different s
|
|||
entryDoorBlock = ModBlocks.blockDimDoor.getDefaultState();
|
||||
}
|
||||
|
||||
World world = DimDoors.proxy.getWorldServer(dimID);
|
||||
WorldServer world = DimDoors.proxy.getWorldServer(dimID);
|
||||
int hLimit = (size + 1) * 16; //horizontal relative limit
|
||||
int yLimit = roofThickness > 0 ? hLimit : 256 - yBase; //vertical relative limit (build-height + 1)
|
||||
|
||||
|
@ -172,16 +198,20 @@ class PocketTemplate { //there is exactly one pocket placer for each different s
|
|||
}
|
||||
}
|
||||
}
|
||||
//@todo Place content from schematic starting at (wallthickness, floorthickness, wallthickness)
|
||||
|
||||
|
||||
BlockPos dungeonBasePos = new BlockPos(xBase + wallThickness, yBase + floorThickness, zBase + wallThickness);
|
||||
|
||||
//Place the Dungeon content structure
|
||||
StructureGenerator.placeStructureAtPosition(new Random(), schematic, Rotation.NONE, world, dungeonBasePos, true);
|
||||
|
||||
//Place the door
|
||||
BlockPos doorPos = new BlockPos(entranceDoorX, entranceDoorY, entranceDoorZ);
|
||||
BlockPos doorPos = dungeonBasePos.offset(EnumFacing.EAST, entranceDoorX).offset(EnumFacing.UP, entranceDoorY).offset(EnumFacing.SOUTH, entranceDoorZ);
|
||||
EnumFacing facing = getAdjacentAirBlockFacing(world, doorPos);
|
||||
entryDoorBlock = entryDoorBlock.withProperty(BlockDoor.FACING, facing);
|
||||
world.setBlockState(doorPos, entryDoorBlock.withProperty(BlockDoor.HALF, EnumDoorHalf.UPPER));
|
||||
world.setBlockState(doorPos, entryDoorBlock.withProperty(BlockDoor.HALF, EnumDoorHalf.LOWER));
|
||||
TileEntity newTileEntity = world.getTileEntity(doorPos);
|
||||
|
||||
|
||||
//Register the rift and return its ID
|
||||
if (newTileEntity instanceof DDTileEntityBase) {
|
||||
DDTileEntityBase newTileEntityDimDoor = (DDTileEntityBase) newTileEntity;
|
||||
|
|
|
@ -5,10 +5,26 @@
|
|||
*/
|
||||
package com.zixiken.dimdoors.shared;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.zixiken.dimdoors.DDConfig;
|
||||
import com.zixiken.dimdoors.DimDoors;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Scanner;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import vazkii.pillar.StructureLoader;
|
||||
import vazkii.pillar.schema.StructureSchema;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -17,22 +33,23 @@ import java.util.Random;
|
|||
public class SchematicHandler {
|
||||
|
||||
public static final SchematicHandler Instance = new SchematicHandler();
|
||||
private PocketTemplate personalPocketSchematic;
|
||||
private PocketTemplate publicPocketSchematic;
|
||||
private List<PocketTemplate> dungeonSchematics;
|
||||
private PocketTemplate personalPocketTemplate;
|
||||
private PocketTemplate publicPocketTemplate;
|
||||
private List<PocketTemplate> dungeonTemplates;
|
||||
//@todo, sort templates by depth over here? that'd mean that that doesn't have to be done on pocket placement each and every time
|
||||
|
||||
PocketTemplate getPersonalPocketSchematic(int maxPocketSize) {
|
||||
return personalPocketSchematic;
|
||||
return personalPocketTemplate;
|
||||
}
|
||||
|
||||
PocketTemplate getPublicPocketSchematic(int maxPocketSize) {
|
||||
return publicPocketSchematic;
|
||||
return publicPocketTemplate;
|
||||
}
|
||||
|
||||
PocketTemplate getRandomDungeonPocketTemplate(int depth, int maxPocketSize) {
|
||||
List<PocketTemplate> validTemplates = new ArrayList();
|
||||
int totalWeight = 0;
|
||||
for (PocketTemplate template : dungeonSchematics) {
|
||||
for (PocketTemplate template : dungeonTemplates) {
|
||||
if (template.getMinDepth() > depth || template.getMaxDepth() < depth) {
|
||||
//do nothing
|
||||
} else {
|
||||
|
@ -40,11 +57,11 @@ public class SchematicHandler {
|
|||
totalWeight += template.getWeight(depth);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Random random = new Random();
|
||||
int chosenTemplatePointer = random.nextInt(totalWeight);
|
||||
for (PocketTemplate template : validTemplates) {
|
||||
if (chosenTemplatePointer < 0) {
|
||||
if (chosenTemplatePointer < 0) {
|
||||
return template;
|
||||
}
|
||||
chosenTemplatePointer -= template.getWeight(depth);
|
||||
|
@ -53,23 +70,124 @@ public class SchematicHandler {
|
|||
}
|
||||
|
||||
public void loadSchematics() {
|
||||
personalPocketSchematic = loadSchematicsFromJson("defaultPersonal", PocketRegistry.Instance.getPrivatePocketSize()).get(0);
|
||||
publicPocketSchematic = loadSchematicsFromJson("defaultPublic", PocketRegistry.Instance.getPublicPocketSize()).get(0);
|
||||
dungeonSchematics = new ArrayList();
|
||||
//@todo, extend the Pillar StructureLoader, so we can load the structures from a different location?
|
||||
StructureLoader.loadStructures(DimDoors.getDefWorld()); //@todo change this to get the DimDoors Dimension?
|
||||
personalPocketTemplate = loadTemplatesFromJson("defaultPersonal", PocketRegistry.Instance.getPrivatePocketSize()).get(0);
|
||||
publicPocketTemplate = loadTemplatesFromJson("defaultPublic", PocketRegistry.Instance.getPublicPocketSize()).get(0);
|
||||
dungeonTemplates = new ArrayList();
|
||||
List<String> dungeonSchematicNameStrings = DDConfig.getDungeonSchematicNames();
|
||||
int maxPocketSize = PocketRegistry.Instance.getMaxPocketSize();
|
||||
for (String nameString : dungeonSchematicNameStrings) {
|
||||
List<PocketTemplate> schematics = loadSchematicsFromJson(nameString, maxPocketSize);
|
||||
if (schematics != null) {
|
||||
for (PocketTemplate schematic : schematics) {
|
||||
dungeonSchematics.add(schematic);
|
||||
List<PocketTemplate> templates = loadTemplatesFromJson(nameString, maxPocketSize);
|
||||
if (templates != null) {
|
||||
for (PocketTemplate template : templates) {
|
||||
if (template != null && template.getSchematic() != null) {
|
||||
dungeonTemplates.add(template);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<PocketTemplate> loadSchematicsFromJson(String nameString, int maxPocketSize) { //depending on the "jSonType" value in the jSon, this might load several variations of a pocket at once
|
||||
//check for json files in both directories (inside the mod jar, and inside the dimdoors config folder)
|
||||
//check if the json has a "variant" with the correct pocket size, if it doesn't, pick the largest smaller variant. If there's only bigger variants, cancel
|
||||
private List<PocketTemplate> loadTemplatesFromJson(String nameString, int maxPocketSize) { //depending on the "jSonType" value in the jSon, this might load several variations of a pocket at once, hence loadTemplate -->s<--
|
||||
File jsonFolder = new File(DDConfig.configurationFolder, "/Jsons");
|
||||
File jsonFile = new File(jsonFolder, "/" + nameString + ".json");
|
||||
String jsonString = null;
|
||||
try {
|
||||
jsonString = readFile(jsonFile.getAbsolutePath(), StandardCharsets.UTF_8);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SchematicHandler.class.getName()).log(Level.SEVERE, "Template Json file for template " + nameString + " was not found in template folder.", ex);
|
||||
}
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonElement jsonElement = parser.parse(jsonString);
|
||||
JsonObject jsonTemplate = jsonElement.getAsJsonObject();
|
||||
List<PocketTemplate> validTemplates = getAllValidVariations(jsonTemplate, maxPocketSize);
|
||||
|
||||
for (PocketTemplate template : validTemplates) { //it's okay to "tap" this for-loop, even if validTemplates is empty.
|
||||
StructureSchema schematic = StructureLoader.loadedSchemas.get(template.getName());
|
||||
template.setSchematic(schematic);
|
||||
//@todo make sure that the dungeon content fits inside the pocket walls (and floor and roof) and otherwise ¿crop it?
|
||||
}
|
||||
//@todo check for json files in both directories (inside the mod jar, and inside the dimdoors config folder)
|
||||
return validTemplates;
|
||||
}
|
||||
|
||||
static String readFile(String path, Charset encoding)
|
||||
throws IOException {
|
||||
byte[] encoded = Files.readAllBytes(Paths.get(path));
|
||||
return new String(encoded, encoding);
|
||||
}
|
||||
|
||||
private List<PocketTemplate> getAllValidVariations(JsonObject jsonTemplate, int maxPocketSize) {
|
||||
String jsonType = jsonTemplate.get("jsonType").getAsString();
|
||||
EnumPocketType pocketType = EnumPocketType.getFromInt(jsonTemplate.get("pocketType").getAsInt());
|
||||
JsonArray variations = jsonTemplate.getAsJsonArray("variations");
|
||||
|
||||
List<PocketTemplate> pocketTemplates = new ArrayList();
|
||||
if (jsonType.equals("Singular")) { //@todo, make sure there is only one Json-reader block, instead of one and its copy
|
||||
JsonObject chosenVariation = null;
|
||||
int chosenVariationSize = 0;
|
||||
for (int i = 0; i < variations.size(); i++) {
|
||||
JsonObject variation = variations.get(i).getAsJsonObject();
|
||||
int variationSize = variation.get("size").getAsInt();
|
||||
if (variationSize <= maxPocketSize && variationSize > chosenVariationSize) {
|
||||
chosenVariationSize = variationSize;
|
||||
chosenVariation = variation;
|
||||
if (variationSize == maxPocketSize) {
|
||||
break; //this one gets chosen
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chosenVariation != null) {
|
||||
//this block equals
|
||||
String variantName = chosenVariation.get("variantName").getAsString();
|
||||
int entranceDoorX = chosenVariation.get("entranceDoorX").getAsInt();
|
||||
int entranceDoorY = chosenVariation.get("entranceDoorY").getAsInt();
|
||||
int entranceDoorZ = chosenVariation.get("entranceDoorZ").getAsInt();
|
||||
int wallThickness = chosenVariation.get("wallThickness").getAsInt();
|
||||
int floorThickness = chosenVariation.get("floorThickness").getAsInt();
|
||||
int roofThickness = chosenVariation.get("roofThickness").getAsInt();
|
||||
EnumPocketType typeID = EnumPocketType.getFromInt(chosenVariation.get("typeID").getAsInt());
|
||||
int minDepth = chosenVariation.get("minDepth").getAsInt();
|
||||
int maxDepth = chosenVariation.get("maxDepth").getAsInt();
|
||||
JsonArray weightsJsonArray = chosenVariation.get("weights").getAsJsonArray();
|
||||
int[] weights = new int[weightsJsonArray.size()];
|
||||
for (int i = 0; i < weightsJsonArray.size(); i++) {
|
||||
weights[i] = weightsJsonArray.get(i).getAsInt();
|
||||
}
|
||||
PocketTemplate pocketTemplate = new PocketTemplate(variantName, chosenVariationSize, entranceDoorX, entranceDoorY, entranceDoorZ,
|
||||
wallThickness, floorThickness, roofThickness, typeID, minDepth, maxDepth, weights);
|
||||
pocketTemplates.add(pocketTemplate);
|
||||
///this block equals
|
||||
}
|
||||
} else if (jsonType.equals("Multiple")) {
|
||||
for (int i = 0; i < variations.size(); i++) {
|
||||
JsonObject variation = variations.get(i).getAsJsonObject();
|
||||
int variationSize = variation.get("size").getAsInt();
|
||||
if (variationSize <= maxPocketSize) {
|
||||
//this block
|
||||
String variantName = variation.get("variantName").getAsString();
|
||||
int entranceDoorX = variation.get("entranceDoorX").getAsInt();
|
||||
int entranceDoorY = variation.get("entranceDoorY").getAsInt();
|
||||
int entranceDoorZ = variation.get("entranceDoorZ").getAsInt();
|
||||
int wallThickness = variation.get("wallThickness").getAsInt();
|
||||
int floorThickness = variation.get("floorThickness").getAsInt();
|
||||
int roofThickness = variation.get("roofThickness").getAsInt();
|
||||
EnumPocketType typeID = EnumPocketType.getFromInt(variation.get("typeID").getAsInt());
|
||||
int minDepth = variation.get("minDepth").getAsInt();
|
||||
int maxDepth = variation.get("maxDepth").getAsInt();
|
||||
JsonArray weightsJsonArray = variation.get("weights").getAsJsonArray();
|
||||
int[] weights = new int[weightsJsonArray.size()];
|
||||
for (int j = 0; j < weightsJsonArray.size(); j++) {
|
||||
weights[j] = weightsJsonArray.get(j).getAsInt();
|
||||
}
|
||||
PocketTemplate pocketTemplate = new PocketTemplate(variantName, variationSize, entranceDoorX, entranceDoorY, entranceDoorZ,
|
||||
wallThickness, floorThickness, roofThickness, typeID, minDepth, maxDepth, weights);
|
||||
pocketTemplates.add(pocketTemplate);
|
||||
///this block
|
||||
}
|
||||
}
|
||||
} //@todo, more options?
|
||||
return pocketTemplates;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue