Implemented usage of Sponge Schematics
-Implemented a way to load these schematics -Implemented a way to place these schematics -Removed "ye olde ways" (Pillar-ways) Todo: -Finding out how and where TileEntities are being created wrongly. -Make pocket-generation a lot less "coupled". Just store the RiftIDs in the Pocket and afterwards ask the pocket for a random RiftID -Do some code cleanup in the SchematicHandler class -Config Dim ID def: 684
This commit is contained in:
parent
732ceee40b
commit
d0b6a74664
4 changed files with 67 additions and 177 deletions
|
@ -114,6 +114,7 @@ public abstract class BlockDimDoorBase extends BlockDoor implements IDimDoor, IT
|
|||
|
||||
@Override
|
||||
public TileEntity createNewTileEntity(World world, int metadata) {
|
||||
Thread.currentThread().getStackTrace();
|
||||
return new TileEntityDimDoor();
|
||||
}
|
||||
|
||||
|
|
|
@ -6,18 +6,15 @@
|
|||
package com.zixiken.dimdoors.shared;
|
||||
|
||||
import com.zixiken.dimdoors.DimDoors;
|
||||
import com.zixiken.dimdoors.blocks.ModBlocks;
|
||||
import com.zixiken.dimdoors.tileentities.DDTileEntityBase;
|
||||
import com.zixiken.dimdoors.tileentities.TileEntityDimDoor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
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.nbt.NBTTagCompound;
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -29,12 +26,6 @@ class PocketTemplate { //there is exactly one pocket placer for each different s
|
|||
//generation parameters
|
||||
private Schematic schematic;
|
||||
private final int size;
|
||||
private final int entranceDoorX;
|
||||
private final int entranceDoorY;
|
||||
private final int entranceDoorZ;
|
||||
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;
|
||||
|
@ -43,7 +34,7 @@ class PocketTemplate { //there is exactly one pocket placer for each different s
|
|||
private final int[] weights; //weights for chanced generation of dungeons per depth level | weights[0] is the weight for depth "minDepth"
|
||||
|
||||
//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, Schematic schematic, int size, int entranceDoorX, int entranceDoorY, int entranceDoorZ, int wallThickness, int floorThickness, int roofThickness, EnumPocketType typeID,
|
||||
public PocketTemplate(String variantName, Schematic schematic, int size, EnumPocketType typeID,
|
||||
int minDepth, int maxDepth, int[] weights) {
|
||||
this.variantName = variantName;
|
||||
this.weights = weights; //chance that this Pocket will get generated
|
||||
|
@ -51,18 +42,11 @@ class PocketTemplate { //there is exactly one pocket placer for each different s
|
|||
this.maxDepth = maxDepth; //to this pocket depth
|
||||
this.size = size; //size of content of pocket in chunks (walls are 5 thick, so size 0 will be 6*6 blocks, size 1 will be 22*22 blocks, etc.
|
||||
this.schematic = schematic;
|
||||
this.entranceDoorX = entranceDoorX; //coords of the TOP HALF of the door
|
||||
this.entranceDoorY = entranceDoorY;
|
||||
this.entranceDoorZ = entranceDoorZ;
|
||||
this.typeID = typeID;
|
||||
this.wallThickness = wallThickness;
|
||||
this.floorThickness = floorThickness;
|
||||
this.roofThickness = roofThickness;
|
||||
}
|
||||
|
||||
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);
|
||||
public PocketTemplate(String variantName, int size, EnumPocketType typeID, int minDepth, int maxDepth, int[] weights) {
|
||||
this(variantName, null, size, typeID, minDepth, maxDepth, weights);
|
||||
}
|
||||
|
||||
int getSize() {
|
||||
|
@ -102,140 +86,49 @@ class PocketTemplate { //there is exactly one pocket placer for each different s
|
|||
DimDoors.log(this.getClass(), "The schematic for variant " + variantName + " somehow didn't load correctly against despite all precautions.");
|
||||
}
|
||||
//@todo make sure that the door tile entities get registered!
|
||||
|
||||
//String tileEntityID = tileEntityTagCompound.getString("id");
|
||||
|
||||
|
||||
IBlockState outerWallBlock = ModBlocks.blockDimWall.getStateFromMeta(2); //@todo, does this return the correct wall?
|
||||
IBlockState innerWallBlock;
|
||||
IBlockState entryDoorBlock;
|
||||
if (typeID == EnumPocketType.PRIVATE) {
|
||||
innerWallBlock = ModBlocks.blockDimWall.getStateFromMeta(1); //@todo, does this return the correct wall?
|
||||
entryDoorBlock = ModBlocks.blockDimDoorPersonal.getDefaultState();
|
||||
} else {
|
||||
innerWallBlock = ModBlocks.blockDimWall.getStateFromMeta(0); //@todo, does this return the correct wall?
|
||||
entryDoorBlock = ModBlocks.blockDimDoor.getDefaultState();
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
//Place walls parallel to the X-axis
|
||||
if (wallThickness > 0) { //only place the walls if there are any walls to be placed
|
||||
//@todo, if I generate all walls from outside to inside in the outer for-loop, that might be better
|
||||
for (int wallLayer = 0; wallLayer < wallThickness; wallLayer++) {
|
||||
IBlockState wallBlock;
|
||||
if (wallLayer == 0) {
|
||||
wallBlock = outerWallBlock;
|
||||
} else {
|
||||
wallBlock = innerWallBlock;
|
||||
}
|
||||
for (int relativeY = 1; relativeY < yLimit - 1; relativeY++) { //the bottom layer will only be generated if the bottom is solid, just like the top
|
||||
if (relativeY == 1) {
|
||||
wallBlock = innerWallBlock; //the outer layer of the wall should be "bedrock", however the bottom of the dimensionwall should always be pitch-black if the dimension doesn't have a bottom for if you fall out of it.
|
||||
}
|
||||
//generate blocks in wall along the x-axis
|
||||
for (int relativeX = 0; relativeX < hLimit; relativeX++) {
|
||||
if (relativeX < wallLayer) {
|
||||
//don't generate
|
||||
} else {
|
||||
world.setBlockState(new BlockPos(xBase + relativeX, yBase + relativeY, zBase + wallLayer), wallBlock);
|
||||
world.setBlockState(new BlockPos(xBase + relativeX, yBase + relativeY, zBase + hLimit - 1 - wallLayer), wallBlock);
|
||||
}
|
||||
}
|
||||
//generate blocks in wall alont the z-axis
|
||||
for (int relativeZ = 0; relativeZ < hLimit; relativeZ++) {
|
||||
if (relativeZ < wallLayer + 1) { //"+1" explanation: The corner blocks are already being placed by the wall along the x-axis
|
||||
//don't generate
|
||||
} else {
|
||||
world.setBlockState(new BlockPos(xBase + wallLayer, yBase + relativeY, zBase + relativeZ), wallBlock);
|
||||
world.setBlockState(new BlockPos(xBase + hLimit - 1 - wallLayer, yBase + relativeY, zBase + relativeZ), wallBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Generate the floor
|
||||
if (floorThickness > 0) {
|
||||
for (int relativeY = 0; relativeY < floorThickness; relativeY++) {
|
||||
IBlockState floorBlock;
|
||||
if (relativeY == 0) {
|
||||
floorBlock = outerWallBlock;
|
||||
} else {
|
||||
floorBlock = innerWallBlock;
|
||||
}
|
||||
for (int relativeX = 0; relativeX < hLimit; relativeX++) {
|
||||
for (int relativeZ = 0; relativeZ < hLimit; relativeZ++) {
|
||||
if (relativeX < wallThickness || relativeX > hLimit - 1 - wallThickness
|
||||
|| relativeZ < wallThickness || relativeZ > hLimit - 1 - wallThickness) { //under the walls
|
||||
if (relativeY == 0) { //only the bottom layer
|
||||
world.setBlockState(new BlockPos(xBase + relativeX, yBase + relativeY, zBase + relativeZ), floorBlock);
|
||||
}
|
||||
} else { //not under the walls
|
||||
world.setBlockState(new BlockPos(xBase + relativeX, yBase + relativeY, zBase + relativeZ), floorBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Generate the roof
|
||||
if (roofThickness > 0) {
|
||||
for (int relativeY = yLimit - 1; relativeY > yLimit - 1 - roofThickness; relativeY--) {
|
||||
IBlockState floorBlock;
|
||||
if (relativeY == 0) {
|
||||
floorBlock = outerWallBlock;
|
||||
} else {
|
||||
floorBlock = innerWallBlock;
|
||||
}
|
||||
for (int relativeX = 0; relativeX < hLimit; relativeX++) {
|
||||
for (int relativeZ = 0; relativeZ < hLimit; relativeZ++) {
|
||||
if (relativeX < wallThickness || relativeX > hLimit - 1 - wallThickness
|
||||
|| relativeZ < wallThickness || relativeZ > hLimit - 1 - wallThickness) { // above the walls
|
||||
if (relativeY == yLimit - 1) { //only the top layer
|
||||
world.setBlockState(new BlockPos(xBase + relativeX, yBase + relativeY, zBase + relativeZ), floorBlock);
|
||||
}
|
||||
} else { //not above the walls
|
||||
world.setBlockState(new BlockPos(xBase + relativeX, yBase + relativeY, zBase + relativeZ), floorBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 = 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;
|
||||
newTileEntityDimDoor.register();
|
||||
return newTileEntityDimDoor.getRiftID();
|
||||
for (int x = 0; x < schematic.width; x++) {
|
||||
for (int y = 0; y < schematic.height; y++) {
|
||||
for (int z = 0; z < schematic.width; z++) {
|
||||
world.setBlockState(new BlockPos(xBase + x, yBase + y, zBase + z), schematic.pallette.get(schematic.blockData[x][y][z]));
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
//Place TileEntities
|
||||
List<DDTileEntityBase> rifts = new ArrayList();
|
||||
for (NBTTagCompound tileEntityNBT : schematic.tileEntities) {
|
||||
BlockPos pos = new BlockPos(xBase + tileEntityNBT.getInteger("x"), yBase + tileEntityNBT.getInteger("y"), zBase + tileEntityNBT.getInteger("z"));
|
||||
IBlockState state = world.getBlockState(pos);
|
||||
state.getBlock().createTileEntity(world, state);
|
||||
TileEntity tileEntity = world.getTileEntity(pos);
|
||||
tileEntity.readFromNBT(tileEntityNBT);
|
||||
tileEntity.markDirty();
|
||||
|
||||
private EnumFacing getAdjacentAirBlockFacing(World world, BlockPos pos) { //@todo, maybe this should be in some utility class?
|
||||
if (world.getBlockState(pos.east()) == Blocks.AIR) {
|
||||
return EnumFacing.EAST;
|
||||
} else if (world.getBlockState(pos.south()) == Blocks.AIR) {
|
||||
return EnumFacing.SOUTH;
|
||||
} else if (world.getBlockState(pos.west()) == Blocks.AIR) {
|
||||
return EnumFacing.WEST;
|
||||
} else { //north or no air blocks adjacent
|
||||
return EnumFacing.NORTH;
|
||||
if (tileEntity instanceof DDTileEntityBase) {
|
||||
DDTileEntityBase rift = (DDTileEntityBase) tileEntity;
|
||||
rifts.add(rift);
|
||||
}
|
||||
}
|
||||
|
||||
List<TileEntityDimDoor> dimDoorTiles = new ArrayList();
|
||||
for (DDTileEntityBase rift : rifts) {
|
||||
rift.register();
|
||||
if (rift instanceof TileEntityDimDoor) {
|
||||
TileEntityDimDoor dimDoorTile = (TileEntityDimDoor) rift;
|
||||
dimDoorTiles.add(dimDoorTile);
|
||||
}
|
||||
}
|
||||
|
||||
if (dimDoorTiles.isEmpty()) {
|
||||
return -1;
|
||||
} else if (dimDoorTiles.size() == 1) {
|
||||
return dimDoorTiles.get(0).getRiftID();
|
||||
} else {
|
||||
Random random = new Random();
|
||||
int index = random.nextInt(dimDoorTiles.size());
|
||||
return dimDoorTiles.get(index).getRiftID();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ import net.minecraft.nbt.NBTTagCompound;
|
|||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||
import net.minecraftforge.fml.common.registry.GameData;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -44,7 +43,7 @@ class Schematic {
|
|||
private Schematic() {
|
||||
}
|
||||
|
||||
Schematic loadFromNBT(NBTTagCompound nbt) {
|
||||
static Schematic loadFromNBT(NBTTagCompound nbt) {
|
||||
Schematic schematic = new Schematic();
|
||||
|
||||
schematic.version = nbt.getInteger("Version");
|
||||
|
@ -93,7 +92,7 @@ class Schematic {
|
|||
blockstate = getBlockStateWithProperties(block, properties); //@todo get the blockState from string
|
||||
} else {
|
||||
}
|
||||
pallette.add(blockstate);
|
||||
schematic.pallette.add(blockstate);
|
||||
}
|
||||
|
||||
byte[] blockDataIntArray = nbt.getByteArray("BlockData");
|
||||
|
@ -115,7 +114,7 @@ class Schematic {
|
|||
return schematic;
|
||||
}
|
||||
|
||||
private IBlockState getBlockStateWithProperties(Block block, String[] properties) {
|
||||
private static IBlockState getBlockStateWithProperties(Block block, String[] properties) {
|
||||
Map<String, String> propertyAndBlockStringsMap = new HashMap();
|
||||
for (int i = 0; i < properties.length; i++) {
|
||||
String propertyString = properties[i];
|
||||
|
|
|
@ -20,9 +20,10 @@ 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 net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -68,8 +69,6 @@ public class SchematicHandler {
|
|||
}
|
||||
|
||||
public void loadSchematics() {
|
||||
|
||||
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();
|
||||
|
@ -90,6 +89,7 @@ public class SchematicHandler {
|
|||
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");
|
||||
File schematicFolder = new File(DDConfig.configurationFolder, "/Schematics");
|
||||
String jsonString = null;
|
||||
try {
|
||||
jsonString = readFile(jsonFile.getAbsolutePath(), StandardCharsets.UTF_8);
|
||||
|
@ -102,9 +102,20 @@ public class SchematicHandler {
|
|||
List<PocketTemplate> validTemplates = getAllValidVariations(jsonTemplate, maxPocketSize);
|
||||
|
||||
for (PocketTemplate template : validTemplates) { //it's okay to "tap" this for-loop, even if validTemplates is empty.
|
||||
Schematic schematic = StructureLoader.loadedSchemas.get(template.getName());
|
||||
File schematicFile = new File(schematicFolder, "/" + template.getName() + ".schem");
|
||||
NBTTagCompound schematicNBT;
|
||||
Schematic schematic = null;
|
||||
try {
|
||||
schematicNBT = CompressedStreamTools.read(schematicFile);
|
||||
schematic = Schematic.loadFromNBT(schematicNBT);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SchematicHandler.class.getName()).log(Level.SEVERE, "Schematic file for schematic " + template.getName() + " was not found in template folder.", ex);
|
||||
}
|
||||
if (schematic != null && (schematic.width > (template.getSize()) * 16 || schematic.length > (template.getSize()) * 16)) {
|
||||
schematic = null;
|
||||
DimDoors.log(this.getClass(), "Schematic " + template.getName() + ".schem was bigger than specified in " + nameString + ".json and therefore wasn't loaded");
|
||||
}
|
||||
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;
|
||||
|
@ -139,12 +150,6 @@ public class SchematicHandler {
|
|||
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();
|
||||
|
@ -153,8 +158,7 @@ public class SchematicHandler {
|
|||
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);
|
||||
PocketTemplate pocketTemplate = new PocketTemplate(variantName, chosenVariationSize, typeID, minDepth, maxDepth, weights);
|
||||
pocketTemplates.add(pocketTemplate);
|
||||
///this block equals
|
||||
}
|
||||
|
@ -165,12 +169,6 @@ public class SchematicHandler {
|
|||
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();
|
||||
|
@ -179,8 +177,7 @@ public class SchematicHandler {
|
|||
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);
|
||||
PocketTemplate pocketTemplate = new PocketTemplate(variantName, variationSize, typeID, minDepth, maxDepth, weights);
|
||||
pocketTemplates.add(pocketTemplate);
|
||||
///this block
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue